<script setup lang="ts">
import {
  ApiOutlined,
  AppstoreOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
  DeleteOutlined,
  DesktopOutlined,
  DownloadOutlined,
  EditOutlined,
  ExclamationCircleOutlined,
  GlobalOutlined,
  LinkOutlined,
  LockOutlined,
  MoreOutlined,
  PlusOutlined,
  ReloadOutlined,
  SearchOutlined,
  SyncOutlined,
} from '@ant-design/icons-vue'
import type {
  DesktopAccountInfo,
  DesktopClientDownloadableRelease,
  EnterpriseSiteCmsType,
  EnterpriseSiteConnection,
  MediaPlatform,
} from '@geo/shared-types'
import { useMutation, useQuery } from '@tanstack/vue-query'
import { Modal, message } from 'ant-design-vue'
import { computed, ref } from 'vue'

import {
  desktopClientApi,
  enterpriseSitesApi,
  mediaApi,
  resolveApiURL,
  tenantAccountsApi,
} from '@/lib/api'
import { resolveAccountCheckedAt, resolveAccountHealth } from '@/lib/desktop-account-runtime'
import { formatBytes, formatDateTime } from '@/lib/display'
import { formatError, formatStoredErrorMessage } from '@/lib/errors'
import {
  getPublishPlatformMeta,
  isMediaPublishAccount,
  normalizePublishPlatformId,
} from '@/lib/publish-platforms'
import { useCompanyStore } from '@/stores/company'

type AccountHealthFilter = 'all' | 'live' | 'captcha' | 'risk' | 'expired'
type PublishState = 'immediate' | 'queued' | 'unavailable'
type MediaScope = 'ugc' | 'enterprise'
type CmsType = EnterpriseSiteCmsType

interface MediaAccountCard {
  id: string
  platform: string
  platformLabel: string
  platformShortName: string
  platformAccent: string
  platformLogoUrl: string | null
  displayName: string
  platformUid: string
  avatarUrl: string | null
  health: DesktopAccountInfo['health']
  verifiedAt: string | null
  clientId: string | null
  clientOnline: boolean | null
  accountSessionOnline: boolean | null
  taskConsumerOnline: boolean | null
  clientDeviceName: string | null
  clientLastSeenAt: string | null
  queuedPublishTaskCount: number
  oldestQueuedPublishTaskAt: string | null
  publishState: PublishState
  publishHint: string
  deleteRequestedAt: string | null
}

interface EnterpriseSiteFormState {
  name: string
  siteUrl: string
  cmsType: CmsType
  appid: string
  secret: string
  defaultAcode: string
  defaultMcode: string
  defaultScode: string
}

const platformLogoCatalog: Record<string, string> = {
  toutiaohao: '/logos/logo_toutiao.png',
  baijiahao: '/logos/logo_baijiahao.png',
  sohuhao: '/logos/logo_souhu.png',
  qiehao: '/logos/logo_qiehao.png',
  zhihu: '/logos/logo_zhihu.png',
  wangyihao: '/logos/logo_wangyihao.png',
  jianshu: '/logos/logo_jianshu.svg',
  bilibili: '/logos/logo_bilibili.png',
  juejin: '/logos/logo_juejin.png',
  smzdm: '/logos/logo_smzdm.svg',
  weixin_gzh: '/logos/logo_weixin_gzh.svg',
  zol: '/logos/logo_zol.png',
  dongchedi: '/logos/logo_dongchedi.svg',
}

const companyStore = useCompanyStore()
const activeMediaScope = ref<MediaScope>('ugc')
const searchQuery = ref('')
const selectedHealth = ref<AccountHealthFilter>('all')
const downloadingReleaseKey = ref<string | null>(null)
const requestingAccountDeleteId = ref<string | null>(null)
const unbindModalOpen = ref(false)
const unbindAccountTarget = ref<MediaAccountCard | null>(null)
const unbindVerifyInput = ref('')
const unbindConfirmLoading = ref(false)

const isUnbindVerified = computed(() => {
  if (!unbindAccountTarget.value) return false
  const targetName = unbindAccountTarget.value.displayName.trim()
  const inputVal = unbindVerifyInput.value.trim()
  return inputVal === targetName || inputVal === '解绑'
})

const enterpriseSiteModalOpen = ref(false)
const editingEnterpriseSiteId = ref<number | null>(null)
const deletingEnterpriseSiteId = ref<number | null>(null)
const failedEnterpriseSiteFavicons = ref<Record<string, boolean>>({})
const enterpriseSiteForm = ref<EnterpriseSiteFormState>({
  name: '',
  siteUrl: '',
  cmsType: 'pbootcms',
  appid: '',
  secret: '',
  defaultAcode: 'cn',
  defaultMcode: '2',
  defaultScode: '',
})
const mediaScopes: Array<{ key: MediaScope; label: string; meta: string }> = [
  { key: 'ugc', label: 'UGC媒体平台', meta: '桌面端账号' },
  { key: 'enterprise', label: '企业自建站点', meta: 'CMS连接' },
]

const cmsTypeOptions: Array<{ label: string; value: CmsType }> = [
  { label: 'PBootCMS', value: 'pbootcms' },
  { label: 'WordPress', value: 'wordpress' },
]

const platformsQuery = useQuery({
  queryKey: ['media', 'platforms', 'media-view'],
  queryFn: () => mediaApi.platforms(),
})

const accountsQuery = useQuery({
  queryKey: ['tenant', 'desktop-accounts', 'media-view'],
  queryFn: () => tenantAccountsApi.list(),
  staleTime: 0,
  refetchInterval: 5_000,
  refetchOnWindowFocus: true,
})

const downloadableReleasesQuery = useQuery({
  queryKey: ['tenant', 'desktop-client', 'downloadable-releases', 'stable'],
  queryFn: async () => {
    try {
      return await desktopClientApi.downloadableReleases('stable')
    } catch {
      return desktopClientApi.publicFallbackDownloadableReleases()
    }
  },
  staleTime: 60_000,
  refetchOnWindowFocus: true,
})

const enterpriseSitesQuery = useQuery({
  queryKey: ['tenant', 'enterprise-sites', 'media-view'],
  queryFn: () => enterpriseSitesApi.list(),
  staleTime: 10_000,
  refetchOnWindowFocus: true,
})

const saveEnterpriseSiteMutation = useMutation({
  mutationFn: () => saveEnterpriseSiteRequest(),
  onSuccess: async (site) => {
    enterpriseSiteModalOpen.value = false
    const wasEditing = editingEnterpriseSiteId.value !== null
    editingEnterpriseSiteId.value = null
    message.success(wasEditing ? '站点连接已更新' : '站点凭证已保存')
    await enterpriseSitesQuery.refetch()
    if (!wasEditing) {
      void enterpriseSitesApi
        .ping(site.id)
        .then(() => enterpriseSitesQuery.refetch())
        .catch(() => undefined)
    }
  },
  onError: (error) => message.error(formatError(error)),
})

const pingEnterpriseSiteMutation = useMutation({
  mutationFn: (siteId: number) => enterpriseSitesApi.ping(siteId),
  onSuccess: async () => {
    message.success('站点连通正常')
    await enterpriseSitesQuery.refetch()
  },
  onError: (error) => message.error(formatError(error)),
})

const syncEnterpriseCategoriesMutation = useMutation({
  mutationFn: (siteId: number) => enterpriseSitesApi.syncCategories(siteId),
  onSuccess: async (categories) => {
    message.success(`已同步 ${categories.length} 个栏目`)
    await enterpriseSitesQuery.refetch()
  },
  onError: (error) => message.error(formatError(error)),
})

const deleteEnterpriseSiteMutation = useMutation({
  mutationFn: (siteId: number) => enterpriseSitesApi.remove(siteId),
  onSuccess: async () => {
    message.success('站点连接已删除')
    await enterpriseSitesQuery.refetch()
  },
  onError: (error) => message.error(formatError(error)),
  onSettled: () => {
    deletingEnterpriseSiteId.value = null
  },
})

const requestAccountDeleteMutation = useMutation({
  mutationFn: (payload: { id: string; undo?: boolean }) =>
    tenantAccountsApi.requestDelete(payload.id, { undo: payload.undo }),
  onSuccess: async (_account, payload) => {
    message.success(payload.undo ? '已撤销解绑申请' : '已申请解绑，客户端会自动清理本地授权')
    await accountsQuery.refetch()
  },
  onError: (error) => message.error(formatError(error)),
  onSettled: () => {
    requestingAccountDeleteId.value = null
  },
})

const removeAccountMutation = useMutation({
  mutationFn: (id: string) => tenantAccountsApi.remove(id),
  onSuccess: async (result) => {
    const cancelledCount = result.cancelled_queued_publish_task_count ?? 0
    message.success(
      cancelledCount > 0
        ? `已完成解绑，并取消 ${cancelledCount} 个排队发布任务`
        : '已完成解绑',
    )
    await accountsQuery.refetch()
  },
  onError: (error) => message.error(formatError(error)),
  onSettled: () => {
    requestingAccountDeleteId.value = null
  },
})

const loading = computed(() => platformsQuery.isPending.value || accountsQuery.isPending.value)
const refreshing = computed(
  () =>
    platformsQuery.isFetching.value ||
    accountsQuery.isFetching.value ||
    downloadableReleasesQuery.isFetching.value ||
    enterpriseSitesQuery.isFetching.value,
)
const enterpriseSiteModalTitle = computed(() =>
  editingEnterpriseSiteId.value === null ? '新增企业站点' : '编辑企业站点',
)
const enterpriseSiteModalOkText = computed(() =>
  editingEnterpriseSiteId.value === null ? '保存凭证' : '保存修改',
)
const enterpriseSiteAppIDLabel = computed(() =>
  enterpriseSiteForm.value.cmsType === 'wordpress' ? '用户名' : 'AppID',
)
const enterpriseSiteAppIDPlaceholder = computed(() =>
  enterpriseSiteForm.value.cmsType === 'wordpress'
    ? 'WordPress 用户名或邮箱'
    : 'PBootCMS 后台 api_appid',
)
const enterpriseSiteSecretPlaceholder = computed(() => {
  if (editingEnterpriseSiteId.value !== null) {
    return '留空则保留原凭证'
  }
  return enterpriseSiteForm.value.cmsType === 'wordpress'
    ? 'WordPress Application Password'
    : 'PBootCMS 后台 api_secret'
})
const enterpriseSiteDefaultScodeLabel = computed(() =>
  enterpriseSiteForm.value.cmsType === 'wordpress' ? '默认分类 ID' : '默认栏目',
)
const enterpriseSiteDefaultScodePlaceholder = computed(() =>
  enterpriseSiteForm.value.cmsType === 'wordpress' ? '例如：12，可选' : '可选',
)

const platformMap = computed(() => {
  return new Map(
    (platformsQuery.data.value ?? []).map((platform: MediaPlatform) => [
      normalizePublishPlatformId(platform.platform_id),
      platform,
    ]),
  )
})

const mediaAccounts = computed<MediaAccountCard[]>(() => {
  return [...(accountsQuery.data.value ?? [])]
    .filter(isMediaPublishAccount)
    .map((account) => {
      const platformId = normalizePublishPlatformId(account.platform)
      const platform = platformMap.value.get(platformId)
      const fallback = getPublishPlatformMeta(platformId)
      const publishState = resolvePublishState(account)
      const health = resolveAccountHealth(account)

      return {
        id: account.id,
        platform: platformId,
        platformLabel: platform?.name || fallback.name,
        platformShortName: platform?.short_name || fallback.shortName,
        platformAccent: platform?.accent_color || fallback.accent,
        platformLogoUrl: resolvePlatformLogoUrl(platformId, platform?.logo_url),
        displayName: account.display_name,
        platformUid: normalizePlatformUid(account.platform_uid),
        avatarUrl: resolveApiURL(account.avatar_url),
        health,
        verifiedAt: resolveAccountCheckedAt(account),
        clientId: account.client_id,
        clientOnline: account.client_online,
        accountSessionOnline: account.account_session_online ?? null,
        taskConsumerOnline: account.task_consumer_online ?? null,
        clientDeviceName: account.client_device_name,
        clientLastSeenAt: account.client_last_seen_at,
        queuedPublishTaskCount: account.queued_publish_task_count ?? 0,
        oldestQueuedPublishTaskAt: account.oldest_queued_publish_task_at ?? null,
        publishState,
        publishHint: resolvePublishHint(account, publishState),
        deleteRequestedAt: account.delete_requested_at,
      }
    })
    .sort((left, right) => {
      const publishGap = publishRank(left.publishState) - publishRank(right.publishState)
      if (publishGap !== 0) {
        return publishGap
      }

      const leftAt = Date.parse(left.verifiedAt ?? '') || 0
      const rightAt = Date.parse(right.verifiedAt ?? '') || 0
      return rightAt - leftAt
    })
})

const overview = computed(() => ({
  total: mediaAccounts.value.length,
  live: mediaAccounts.value.filter((item) => item.health === 'live').length,
  immediate: mediaAccounts.value.filter((item) => item.publishState === 'immediate').length,
  queued: mediaAccounts.value.filter((item) => item.publishState === 'queued').length,
  attention: mediaAccounts.value.filter((item) => item.publishState === 'unavailable').length,
}))

const enterpriseOverview = computed(() => {
  const sites = enterpriseSites.value
  const publishable = sites.filter((site) => site.status === 'connected').length
  return {
    total: sites.length,
    publishable,
    attention: sites.length - publishable,
    categories: sites.reduce((acc, site) => acc + (site.category_count || 0), 0),
  }
})

const filteredAccounts = computed(() => {
  const keyword = searchQuery.value.trim().toLowerCase()

  return mediaAccounts.value.filter((account) => {
    if (selectedHealth.value !== 'all' && account.health !== selectedHealth.value) {
      return false
    }

    if (!keyword) {
      return true
    }

    return [
      account.displayName,
      account.platformLabel,
      account.platformUid,
      account.clientDeviceName ?? '',
    ]
      .join(' ')
      .toLowerCase()
      .includes(keyword)
  })
})

const downloadableReleases = computed(() => downloadableReleasesQuery.data.value?.items ?? [])
const enterpriseSites = computed(() => enterpriseSitesQuery.data.value ?? [])
const downloadableReleasesError = computed(() => {
  const error = downloadableReleasesQuery.error.value
  if (!error) {
    return ''
  }
  if (error instanceof Error) {
    return error.message
  }
  return String(error)
})

function resolvePublishState(account: DesktopAccountInfo): PublishState {
  if (account.delete_requested_at) {
    return 'unavailable'
  }
  if (resolveAccountHealth(account) !== 'live') {
    return 'unavailable'
  }
  if (!account.client_id) {
    return 'unavailable'
  }
  return account.task_consumer_online === true ? 'immediate' : 'queued'
}

function resolvePublishHint(account: DesktopAccountInfo, publishState: PublishState): string {
  if (account.delete_requested_at) {
    return '此运行节点绑定正在解绑中，不会再接收新的发布任务。'
  }
  if (publishState === 'immediate') {
    return ''
  }
  if (publishState === 'queued') {
    const count = account.queued_publish_task_count ?? 0
    const prefix = count > 0 ? `当前已有 ${count} 个发布任务排队。` : ''
    if (account.client_online === true) {
      return `${prefix}客户端心跳在线，但任务消费通道未就绪；任务会进入发布队列，通道恢复后自动继续。`
    }
    return `${prefix}客户端当前离线，任务会先进入发布队列，等桌面端上线后自动继续。`
  }
  if (resolveAccountHealth(account) !== 'live') {
    return '授权状态异常，先在桌面端重新校验后再发布。'
  }
  return '还没有绑定桌面客户端，当前无法加入发布队列。'
}

function normalizePlatformUid(value?: string | null): string {
  let normalized = String(value ?? '').trim()
  while (normalized.toLowerCase().startsWith('platform:')) {
    normalized = normalized.slice('platform:'.length).trim()
  }
  return normalized || '--'
}

function resolvePlatformLogoUrl(platformId: string, remoteLogoUrl?: string | null): string | null {
  const localLogoUrl = platformLogoCatalog[platformId]
  if (localLogoUrl) {
    return localLogoUrl
  }

  const resolvedRemoteLogoUrl = resolveApiURL(remoteLogoUrl)
  return resolvedRemoteLogoUrl || null
}

function accountInitial(account: MediaAccountCard): string {
  const name = account.displayName.trim()
  return name ? name.slice(0, 1).toUpperCase() : account.platformShortName
}

function publishRank(state: PublishState): number {
  switch (state) {
    case 'immediate':
      return 0
    case 'queued':
      return 1
    default:
      return 2
  }
}

function healthLabel(health: DesktopAccountInfo['health']): string {
  switch (health) {
    case 'live':
      return '授权正常'
    case 'captcha':
      return '待处理'
    case 'risk':
      return '风险观察'
    default:
      return '授权异常'
  }
}

function healthColor(health: DesktopAccountInfo['health']): string {
  switch (health) {
    case 'live':
      return 'green'
    case 'captcha':
      return 'orange'
    case 'risk':
      return 'gold'
    default:
      return 'red'
  }
}

function clientStatusLabel(account: MediaAccountCard): string {
  if (!account.clientId) {
    return '未绑定'
  }
  if (account.taskConsumerOnline) {
    return '任务通道在线'
  }
  return account.clientOnline ? '心跳在线，任务通道离线' : '离线'
}

function clientStatusColor(account: MediaAccountCard): string {
  if (!account.clientId) {
    return 'default'
  }
  if (account.taskConsumerOnline) {
    return 'green'
  }
  return account.clientOnline ? 'orange' : 'gold'
}

function clientStatusText(account: MediaAccountCard): string {
  if (!account.clientId) {
    return '未绑定桌面客户端'
  }

  const device = account.clientDeviceName?.trim()
  return device ? `${clientStatusLabel(account)} · ${device}` : clientStatusLabel(account)
}

function publishStateLabel(state: PublishState): string {
  switch (state) {
    case 'immediate':
      return '可立即发布'
    case 'queued':
      return '排队等待'
    default:
      return '不可发布'
  }
}

function publishStateColor(state: PublishState): string {
  switch (state) {
    case 'immediate':
      return 'green'
    case 'queued':
      return 'gold'
    default:
      return 'red'
  }
}

async function refreshAll(): Promise<void> {
  await Promise.all([
    platformsQuery.refetch(),
    accountsQuery.refetch(),
    downloadableReleasesQuery.refetch(),
    enterpriseSitesQuery.refetch(),
  ])
}

function openEnterpriseSiteModal(cmsType: CmsType = 'pbootcms'): void {
  editingEnterpriseSiteId.value = null
  enterpriseSiteForm.value = {
    name: '',
    siteUrl: '',
    cmsType,
    appid: '',
    secret: '',
    defaultAcode: cmsType === 'wordpress' ? '' : 'cn',
    defaultMcode: cmsType === 'wordpress' ? '' : '2',
    defaultScode: '',
  }
  enterpriseSiteModalOpen.value = true
}

function openEnterpriseSiteEditModal(site: EnterpriseSiteConnection): void {
  editingEnterpriseSiteId.value = site.id
  enterpriseSiteForm.value = {
    name: site.name,
    siteUrl: site.site_url,
    cmsType: site.cms_type as CmsType,
    appid: site.appid,
    secret: '',
    defaultAcode: site.default_acode ?? 'cn',
    defaultMcode: site.default_mcode ?? '2',
    defaultScode: site.default_scode ?? '',
  }
  enterpriseSiteModalOpen.value = true
}

function closeEnterpriseSiteModal(): void {
  enterpriseSiteModalOpen.value = false
  editingEnterpriseSiteId.value = null
}

function handleEnterpriseSiteCMSTypeChange(value: CmsType): void {
  enterpriseSiteForm.value = {
    ...enterpriseSiteForm.value,
    cmsType: value,
    defaultAcode: value === 'wordpress' ? '' : 'cn',
    defaultMcode: value === 'wordpress' ? '' : '2',
    defaultScode: '',
  }
}

function getEnterpriseSiteSelectPopupContainer(triggerNode: HTMLElement): HTMLElement {
  return (triggerNode.closest('.ant-modal-content') as HTMLElement) || document.body
}

function normalizeSiteUrl(value: string): string {
  const trimmed = value.trim()
  if (!trimmed) {
    return ''
  }
  return /^https?:\/\//i.test(trimmed)
    ? trimmed.replace(/\/+$/, '')
    : `https://${trimmed}`.replace(/\/+$/, '')
}

async function saveEnterpriseSiteRequest(): Promise<EnterpriseSiteConnection> {
  const form = enterpriseSiteForm.value
  const siteUrl = normalizeSiteUrl(form.siteUrl)
  const appid = form.appid.trim()
  const secret = form.secret.trim()
  const editingId = editingEnterpriseSiteId.value

  if (!siteUrl || !appid || (editingId === null && !secret)) {
    throw new Error('请填写站点域名、AppID、Secret')
  }
  let name = form.name.trim()
  try {
    name = name || new URL(siteUrl).hostname
  } catch {
    throw new Error('站点域名格式不正确')
  }
  if (editingId !== null) {
    return enterpriseSitesApi.update(editingId, {
      name,
      site_url: siteUrl,
      appid,
      secret: secret || undefined,
      default_acode: form.defaultAcode.trim() || null,
      default_mcode: form.defaultMcode.trim() || null,
      default_scode: form.defaultScode.trim() || null,
    })
  }
  return enterpriseSitesApi.create({
    name,
    site_url: siteUrl,
    cms_type: form.cmsType,
    appid,
    secret,
    default_acode: form.defaultAcode.trim() || null,
    default_mcode: form.defaultMcode.trim() || null,
    default_scode: form.defaultScode.trim() || null,
  })
}

function cmsTypeLabel(cmsType: CmsType): string {
  return cmsTypeOptions.find((option) => option.value === cmsType)?.label ?? cmsType
}

function enterpriseSiteCredentialLabel(site: EnterpriseSiteConnection): string {
  return String(site.cms_type).trim() === 'wordpress' ? '用户名' : 'AppID'
}

function enterpriseSiteStatusLabel(status: string): string {
  switch (status) {
    case 'connected':
      return '已连通'
    case 'error':
      return '连接异常'
    case 'disabled':
      return '已禁用'
    default:
      return '待校验'
  }
}

function enterpriseSiteStatusColor(status: string): string {
  switch (status) {
    case 'connected':
      return 'green'
    case 'error':
      return 'red'
    case 'disabled':
      return 'default'
    default:
      return 'gold'
  }
}

function syncEnterpriseCategories(site: EnterpriseSiteConnection): void {
  syncEnterpriseCategoriesMutation.mutate(site.id)
}

function pingEnterpriseSite(site: EnterpriseSiteConnection): void {
  pingEnterpriseSiteMutation.mutate(site.id)
}

function deleteEnterpriseSite(site: EnterpriseSiteConnection): void {
  Modal.confirm({
    title: '确认删除这个站点连接？',
    content: '删除后，绑定该站点的发文通道将被清除，且无法恢复。确定继续吗？',
    okText: '删除',
    cancelText: '取消',
    okButtonProps: { danger: true },
    onOk: () => {
      deletingEnterpriseSiteId.value = site.id
      deleteEnterpriseSiteMutation.mutate(site.id)
    },
  })
}

function requestUnbindAccount(account: MediaAccountCard): void {
  unbindAccountTarget.value = account
  unbindVerifyInput.value = ''
  unbindConfirmLoading.value = false
  unbindModalOpen.value = true
}

async function handleConfirmUnbind(): Promise<void> {
  if (!isUnbindVerified.value || !unbindAccountTarget.value) return

  unbindConfirmLoading.value = true
  try {
    requestingAccountDeleteId.value = unbindAccountTarget.value.id
    await removeAccountMutation.mutateAsync(unbindAccountTarget.value.id)
    unbindModalOpen.value = false
  } catch (err) {
    // Error is handled by removeAccountMutation onError
  } finally {
    unbindConfirmLoading.value = false
  }
}

function undoUnbindAccount(account: MediaAccountCard): void {
  requestingAccountDeleteId.value = account.id
  requestAccountDeleteMutation.mutate({ id: account.id, undo: true })
}

function isAccountDeleteRequestPending(accountId: string): boolean {
  return (
    (requestAccountDeleteMutation.isPending.value || removeAccountMutation.isPending.value) &&
    requestingAccountDeleteId.value === accountId
  )
}

function enterpriseSiteFaviconURL(site: EnterpriseSiteConnection): string {
  try {
    const parsed = new URL(site.site_url)
    return `${parsed.origin}/favicon.ico`
  } catch {
    return ''
  }
}

function enterpriseSiteFaviconKey(site: EnterpriseSiteConnection): string {
  return `${site.id}:${enterpriseSiteFaviconURL(site)}`
}

function shouldShowEnterpriseSiteFavicon(site: EnterpriseSiteConnection): boolean {
  const faviconURL = enterpriseSiteFaviconURL(site)
  return Boolean(faviconURL && !failedEnterpriseSiteFavicons.value[enterpriseSiteFaviconKey(site)])
}

function markEnterpriseSiteFaviconFailed(site: EnterpriseSiteConnection): void {
  failedEnterpriseSiteFavicons.value = {
    ...failedEnterpriseSiteFavicons.value,
    [enterpriseSiteFaviconKey(site)]: true,
  }
}

function enterpriseSiteLastError(site: EnterpriseSiteConnection): string {
  return formatStoredErrorMessage(site.last_error)
}

async function downloadRelease(release: DesktopClientDownloadableRelease): Promise<void> {
  const key = releaseDownloadKey(release)
  if (downloadingReleaseKey.value) {
    return
  }

  downloadingReleaseKey.value = key
  const downloadWindow = window.open('about:blank', '_blank')
  if (downloadWindow) {
    downloadWindow.opener = null
  }
  try {
    const result = await desktopClientApi.publicDownloadURL({
      platform: release.platform,
      arch: release.arch,
      channel: release.channel,
    })
    const downloadURL = String(result.download_url ?? '').trim()
    if (!downloadURL) {
      message.warning('下载地址为空')
      downloadWindow?.close()
      return
    }
    if (downloadWindow) {
      downloadWindow.location.href = downloadURL
    } else {
      window.open(downloadURL, '_blank', 'noopener,noreferrer')
    }
  } catch (error) {
    downloadWindow?.close()
    const detail =
      typeof error === 'object' && error !== null && 'detail' in error ? error.detail : null
    const reason =
      typeof detail === 'string' && detail.trim()
        ? detail
        : error instanceof Error
          ? error.message
          : '请稍后重试'
    message.error(`获取下载地址失败：${reason}`)
  } finally {
    if (downloadingReleaseKey.value === key) {
      downloadingReleaseKey.value = null
    }
  }
}

function releaseDownloadKey(release: DesktopClientDownloadableRelease): string {
  return `${release.platform}:${release.arch}:${release.channel}`
}

function releaseTargetLabel(release: DesktopClientDownloadableRelease): string {
  return `${releasePlatformLabel(release.platform)} ${releaseArchLabel(release.arch)}`
}

function releasePlatformLabel(platform: string): string {
  switch (platform) {
    case 'darwin':
      return 'macOS'
    case 'win32':
      return 'Windows'
    case 'linux':
      return 'Linux'
    default:
      return platform
  }
}

function releaseArchLabel(arch: string): string {
  switch (arch) {
    case 'arm64':
      return 'ARM64'
    case 'x64':
      return 'x64'
    case 'ia32':
      return 'ia32'
    case 'universal':
      return 'Universal'
    default:
      return arch
  }
}

function releaseDate(release: DesktopClientDownloadableRelease): string {
  return formatDateTime(release.published_at ?? release.updated_at)
}

function releaseSize(value?: number | null): string {
  return typeof value === 'number' && Number.isFinite(value) ? formatBytes(value) : '--'
}
</script>

<template>
  <div class="media-view">
    <!-- Premium Dark Banner Section -->
    <section class="media-view__top-card">
      <div class="media-view__header">
        <div class="media-view__header-title">
          <h2>媒体管理</h2>
          <p>将 UGC 账号、新闻源资源和企业自建站点分开管理，发布链路按目标类型独立执行。</p>
        </div>
        <div class="media-view__header-actions">
          <a-button class="btn-refresh" :loading="refreshing" @click="refreshAll">
            <template #icon><ReloadOutlined /></template>
            刷新状态
          </a-button>
        </div>
      </div>

      <div class="media-scope-tabs">
        <button
          v-for="scope in mediaScopes"
          :key="scope.key"
          class="media-scope-tab"
          :class="{ 'media-scope-tab--active': activeMediaScope === scope.key }"
          type="button"
          @click="activeMediaScope = scope.key"
        >
          <DesktopOutlined v-if="scope.key === 'ugc'" class="tab-icon" />
          <GlobalOutlined v-else-if="scope.key === 'enterprise'" class="tab-icon" />
          <span>{{ scope.label }}</span>
          <small>{{ scope.meta }}</small>
        </button>
      </div>

      <div v-if="activeMediaScope === 'ugc'" class="overview-strip border-t">
        <div class="overview-chip">
          <div class="chip-icon-box total-bg">
            <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
              <path
                d="M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2zm1 14h-2v-6h2v6zm0-8h-2V6h2v2z"
              />
            </svg>
          </div>
          <div class="chip-copy">
            <span>账号总数</span>
            <strong>{{ overview.total }}</strong>
          </div>
        </div>
        <div class="overview-chip">
          <div class="chip-icon-box live-bg">
            <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
              <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" />
            </svg>
          </div>
          <div class="chip-copy">
            <span>可立即发布</span>
            <strong>{{ overview.immediate }}</strong>
          </div>
        </div>
        <div class="overview-chip">
          <div class="chip-icon-box queued-bg">
            <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
              <path
                d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z"
              />
            </svg>
          </div>
          <div class="chip-copy">
            <span>排队等待</span>
            <strong>{{ overview.queued }}</strong>
          </div>
        </div>
        <div class="overview-chip">
          <div class="chip-icon-box attention-bg">
            <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
              <path
                d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"
              />
            </svg>
          </div>
          <div class="chip-copy">
            <span>需处理</span>
            <strong>{{ overview.attention }}</strong>
          </div>
        </div>
      </div>

      <div v-if="activeMediaScope === 'enterprise'" class="overview-strip border-t">
        <div class="overview-chip">
          <div class="chip-icon-box total-bg">
            <GlobalOutlined />
          </div>
          <div class="chip-copy">
            <span>站点总数</span>
            <strong>{{ enterpriseOverview.total }}</strong>
          </div>
        </div>
        <div class="overview-chip">
          <div class="chip-icon-box live-bg">
            <CheckCircleOutlined />
          </div>
          <div class="chip-copy">
            <span>可发布站点</span>
            <strong>{{ enterpriseOverview.publishable }}</strong>
          </div>
        </div>
        <div class="overview-chip">
          <div class="chip-icon-box queued-bg">
            <CloseCircleOutlined />
          </div>
          <div class="chip-copy">
            <span>待处理站点</span>
            <strong>{{ enterpriseOverview.attention }}</strong>
          </div>
        </div>
        <div class="overview-chip">
          <div class="chip-icon-box total-bg">
            <AppstoreOutlined />
          </div>
          <div class="chip-copy">
            <span>栏目总数</span>
            <strong>{{ enterpriseOverview.categories }}</strong>
          </div>
        </div>
      </div>
    </section>

    <template v-if="activeMediaScope === 'enterprise'">
      <section class="enterprise-grid enterprise-grid--single">
        <article class="panel connector-panel">
          <div class="panel-head-compact">
            <div>
              <h3 class="panel-title">企业自建站点</h3>
              <p class="panel-desc">
                管理客户官网、品牌站、行业站的连接凭证和连通状态。发布结果统一进入发文管理查看。
              </p>
            </div>
            <div class="panel-head-actions">
              <a-button
                type="primary"
                class="btn-enterprise-primary"
                @click="openEnterpriseSiteModal()"
              >
                <template #icon><PlusOutlined /></template>
                新增站点
              </a-button>
            </div>
          </div>

          <a-spin :spinning="enterpriseSitesQuery.isPending.value">
            <div v-if="!enterpriseSites.length" class="connector-empty-premium">
              <div class="empty-glow"></div>
              <div class="empty-icon-wrapper">
                <GlobalOutlined class="empty-globe" />
                <PlusOutlined class="empty-plus" />
              </div>
              <h3>暂无企业自建站点</h3>
              <p>
                对接您的 CMS 站点（如 PBootCMS、WordPress 等）后，系统将能够通过 API
                自动将文章推送到您的自建网站，实现多渠道一键发布与同步。
              </p>
              <a-button
                type="primary"
                size="large"
                class="btn-empty-add"
                @click="openEnterpriseSiteModal()"
              >
                <template #icon><PlusOutlined /></template>
                立即添加第一个站点
              </a-button>
            </div>

            <div v-else class="site-connection-grid">
              <article v-for="site in enterpriseSites" :key="site.id" class="site-connection-card">
                <!-- Top accent based on status -->
                <div class="site-card-accent" :class="`accent-${site.status || 'pending'}`"></div>

                <div class="site-connection-card__header">
                  <span class="site-connection-card__icon">
                    <img
                      v-if="shouldShowEnterpriseSiteFavicon(site)"
                      :src="enterpriseSiteFaviconURL(site)"
                      :alt="`${site.name} 站点图标`"
                      class="site-connection-card__favicon"
                      @error="markEnterpriseSiteFaviconFailed(site)"
                    />
                    <GlobalOutlined v-else />
                  </span>

                  <div class="site-connection-card__header-main">
                    <div class="site-name-row">
                      <h4>{{ site.name }}</h4>
                      <span class="site-badge site-badge--cms">
                        {{ cmsTypeLabel(site.cms_type as CmsType) }}
                      </span>
                    </div>

                    <span
                      class="site-badge site-badge--status"
                      :class="`site-badge--status-${site.status || 'pending'}`"
                    >
                      <span class="site-badge__dot"></span>
                      {{ enterpriseSiteStatusLabel(site.status) }}
                    </span>
                  </div>
                </div>

                <div class="site-connection-card__content">
                  <div class="site-url-box">
                    <a :href="site.site_url" target="_blank" rel="noreferrer" class="site-link">
                      <LinkOutlined class="link-icon" />
                      <span>{{ site.site_url }}</span>
                    </a>
                  </div>

                  <div class="site-meta-grid">
                    <div class="meta-cell">
                      <span class="meta-label">{{ enterpriseSiteCredentialLabel(site) }}</span>
                      <span class="meta-value" :title="site.appid">{{ site.appid }}</span>
                    </div>
                    <div class="meta-cell">
                      <span class="meta-label">栏目</span>
                      <span class="meta-value">{{ site.category_count }} 个</span>
                    </div>
                    <div class="meta-cell full-width">
                      <span class="meta-label">栏目同步</span>
                      <span class="meta-value">
                        {{ site.last_sync_at ? formatDateTime(site.last_sync_at) : '待同步' }}
                      </span>
                    </div>
                  </div>
                </div>

                <div class="site-connection-card__footer-actions">
                  <a-button
                    size="middle"
                    class="btn-action-ping"
                    :loading="
                      pingEnterpriseSiteMutation.isPending.value &&
                      pingEnterpriseSiteMutation.variables.value === site.id
                    "
                    @click="pingEnterpriseSite(site)"
                  >
                    <template #icon><ApiOutlined /></template>
                    测试连接
                  </a-button>

                  <div class="footer-actions-right">
                    <a-button
                      size="middle"
                      class="btn-action-sync"
                      :loading="
                        syncEnterpriseCategoriesMutation.isPending.value &&
                        syncEnterpriseCategoriesMutation.variables.value === site.id
                      "
                      @click="syncEnterpriseCategories(site)"
                    >
                      <template #icon><SyncOutlined /></template>
                      同步栏目
                    </a-button>

                    <a-dropdown :trigger="['click']" placement="bottomRight">
                      <a-button size="middle" class="action-more-btn" type="text" @click.stop>
                        <template #icon><MoreOutlined /></template>
                      </a-button>
                      <template #overlay>
                        <a-menu>
                          <a-menu-item key="edit" @click="openEnterpriseSiteEditModal(site)">
                            <EditOutlined />
                            <span>编辑站点</span>
                          </a-menu-item>
                          <a-menu-divider />
                          <a-menu-item key="delete" danger @click="deleteEnterpriseSite(site)">
                            <DeleteOutlined />
                            <span>删除站点</span>
                          </a-menu-item>
                        </a-menu>
                      </template>
                    </a-dropdown>
                  </div>
                </div>

                <div
                  v-if="enterpriseSiteLastError(site)"
                  class="site-connection-card__error-banner"
                >
                  <ExclamationCircleOutlined class="error-banner-icon" />
                  <div class="error-banner-content">
                    <div class="error-banner-title">连接失败诊断</div>
                    <div class="error-banner-desc">{{ enterpriseSiteLastError(site) }}</div>
                  </div>
                </div>
              </article>
            </div>
          </a-spin>
        </article>
      </section>
    </template>

    <template v-else>
      <!-- Client Download Section (App Store Style) -->
      <section class="panel client-download-panel">
        <div class="client-download-head">
          <div>
            <div class="title-with-badge">
              <h3 class="panel-title">客户端下载</h3>
              <span class="badge-pulsing-stable">Stable</span>
            </div>
            <p class="panel-desc">高并发发布与任务执行节点，版本根据后台发布配置自动更新与推送。</p>
          </div>
        </div>

        <a-spin :spinning="downloadableReleasesQuery.isPending.value">
          <a-alert
            v-if="downloadableReleasesError"
            type="warning"
            show-icon
            class="premium-alert"
            :message="`客户端列表读取失败：${downloadableReleasesError}`"
          />

          <a-empty
            v-else-if="!downloadableReleases.length"
            class="premium-empty"
            description="当前暂无可下载客户端，请等待运营后台发布。"
          />

          <div v-else class="client-download-grid">
            <article
              v-for="release in downloadableReleases"
              :key="release.id"
              class="client-download-card"
            >
              <div class="client-download-card__body">
                <div class="client-download-card__logo" :class="`logo-${release.platform}`">
                  <template v-if="release.platform === 'darwin'">
                    <svg viewBox="0 0 24 24" class="os-svg-icon">
                      <path
                        fill="currentColor"
                        d="M18.71,19.5 C17.88,20.74 17,21.95 15.66,21.97 C14.32,22 13.89,21.18 12.37,21.18 C10.84,21.18 10.37,21.95 9.1,22 C7.79,22.05 6.8,20.68 5.96,19.48 C4.25,17 2.94,12.45 4.7,9.39 C5.57,7.87 7.13,6.91 8.82,6.88 C10.1,6.86 11.32,7.75 12.11,7.75 C12.89,7.75 14.37,6.68 15.92,6.84 C16.57,6.87 18.39,7.1 19.56,8.82 C19.47,8.88 17.39,10.1 17.41,12.63 C17.44,15.65 20.06,16.66 20.1,16.67 C20.08,16.74 19.67,18.11 18.71,19.5 M15.97,4.17 C16.63,3.37 17.07,2.28 16.95,1 C16,1.04 14.9,1.6 14.24,2.38 C13.68,3.04 13.19,4.14 13.34,5.39 C14.39,5.47 15.4,4.88 15.97,4.17 Z"
                      />
                    </svg>
                  </template>
                  <template v-else-if="release.platform === 'win32'">
                    <svg viewBox="0 0 24 24" class="os-svg-icon">
                      <path
                        fill="currentColor"
                        d="M0 3.449L9.75 2.1v9.45H0V3.449zM0 12.45h9.75v9.45L0 20.551V12.45zm11.25-10.549L24 0v11.55H11.25V1.901zM11.25 12.45H24v11.55l-12.75-1.901V12.45z"
                      />
                    </svg>
                  </template>
                  <template v-else>
                    <svg
                      viewBox="0 0 24 24"
                      class="os-svg-icon"
                      stroke="currentColor"
                      fill="none"
                      stroke-width="2"
                      stroke-linecap="round"
                      stroke-linejoin="round"
                    >
                      <polyline points="4 17 10 11 4 5"></polyline>
                      <line x1="12" y1="19" x2="20" y2="19"></line>
                    </svg>
                  </template>
                </div>
                <div class="client-download-card__content">
                  <h4>{{ releaseTargetLabel(release) }}</h4>
                  <div class="meta-inline">
                    <span class="version-tag">v{{ release.version }}</span>
                    <span class="dot-separator">•</span>
                    <span>{{ releaseSize(release.file_size_bytes) }}</span>
                    <span class="dot-separator">•</span>
                    <span>{{ releaseDate(release) }}</span>
                  </div>
                </div>
              </div>

              <div class="client-download-card__file">
                <span class="file-icon">
                  <svg
                    viewBox="0 0 24 24"
                    width="12"
                    height="12"
                    fill="none"
                    stroke="currentColor"
                    stroke-width="2"
                  >
                    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
                    <polyline points="14 2 14 8 20 8"></polyline>
                  </svg>
                </span>
                <span class="file-name" :title="release.file_name || '安装包'">
                  {{ release.file_name || '安装包' }}
                </span>
              </div>

              <div class="client-download-card__actions">
                <a-button
                  type="primary"
                  class="btn-download"
                  :loading="downloadingReleaseKey === releaseDownloadKey(release)"
                  :disabled="Boolean(downloadingReleaseKey)"
                  @click="downloadRelease(release)"
                >
                  <template #icon><DownloadOutlined /></template>
                  获取客户端
                </a-button>
              </div>
            </article>
          </div>
        </a-spin>
      </section>

      <!-- Bound accounts grid section -->
      <section class="panel media-list-panel">
        <div class="media-list-header-row">
          <div class="media-list-title-box">
            <h3 class="panel-title">已绑定媒体账号</h3>
            <p class="panel-desc">管理各媒体账号的授权效期、排队就绪状态和客户端物理节点映射。</p>
          </div>

          <div class="media-list-toolbar">
            <a-input
              v-model:value="searchQuery"
              placeholder="搜索账号昵称、UID、发布渠道..."
              class="media-search"
              allow-clear
            >
              <template #prefix>
                <SearchOutlined style="color: #a0aec0" />
              </template>
            </a-input>

            <a-select v-model:value="selectedHealth" class="media-select" style="width: 150px">
              <a-select-option value="all">全部状态</a-select-option>
              <a-select-option value="live">授权正常</a-select-option>
              <a-select-option value="captcha">待处理</a-select-option>
              <a-select-option value="risk">风险观察</a-select-option>
              <a-select-option value="expired">授权异常</a-select-option>
            </a-select>
          </div>
        </div>

        <a-spin :spinning="loading">
          <a-empty
            v-if="!filteredAccounts.length"
            class="premium-empty"
            description="没有符合过滤条件的媒体账号，请确保桌面端客户端在线并已绑定账号。"
          />

          <section v-else class="media-grid">
            <article v-for="account in filteredAccounts" :key="account.id" class="media-card">
              <!-- Top brand line accent using accent color -->
              <div
                class="media-card__accent-bar"
                :style="{ background: account.platformAccent }"
              ></div>

              <div class="media-card__head">
                <div class="media-card__identity">
                  <span
                    class="media-card__avatar"
                    :style="{ border: `2px solid ${account.platformAccent}` }"
                  >
                    <img
                      v-if="account.avatarUrl"
                      :src="account.avatarUrl"
                      :alt="account.displayName"
                      referrerpolicy="no-referrer"
                    />
                    <span
                      v-else
                      class="avatar-initial"
                      :style="{ background: account.platformAccent }"
                    >
                      {{ accountInitial(account) }}
                    </span>
                  </span>

                  <div class="media-card__identity-copy">
                    <h3 :title="account.displayName">
                      {{ account.displayName }}
                      <span class="platform-logo-container">
                        <img
                          v-if="account.platformLogoUrl"
                          :src="account.platformLogoUrl"
                          :alt="account.platformLabel"
                          class="media-card__inline-platform-icon"
                        />
                        <span
                          v-else
                          class="media-card__inline-platform-text"
                          :style="{
                            color: account.platformAccent,
                            background: `${account.platformAccent}15`,
                          }"
                        >
                          {{ account.platformShortName }}
                        </span>
                      </span>
                    </h3>
                    <p>
                      <span class="media-card__platform-name">{{ account.platformLabel }}</span>
                      <span class="media-card__uid-divider">•</span>
                      <span class="media-card__uid" :title="account.platformUid">
                        ID: {{ account.platformUid }}
                      </span>
                    </p>
                  </div>
                </div>

                <a-dropdown :trigger="['click']" placement="bottomRight" overlayClassName="premium-unbind-dropdown">
                  <a-button
                    type="text"
                    class="media-card__more"
                    :loading="isAccountDeleteRequestPending(account.id)"
                    @click.stop
                  >
                    <template #icon><MoreOutlined /></template>
                  </a-button>
                  <template #overlay>
                    <a-menu>
                      <a-menu-item
                        v-if="account.deleteRequestedAt"
                        key="complete-unbind"
                        danger
                        @click="requestUnbindAccount(account)"
                      >
                        <DeleteOutlined />
                        <span>完成解绑</span>
                      </a-menu-item>
                      <a-menu-item
                        v-if="account.deleteRequestedAt"
                        key="undo-unbind"
                        @click="undoUnbindAccount(account)"
                      >
                        <SyncOutlined />
                        <span>撤销解绑申请</span>
                      </a-menu-item>
                      <a-menu-item
                        v-else
                        key="unbind"
                        danger
                        @click="requestUnbindAccount(account)"
                      >
                        <DeleteOutlined />
                        <span>解绑账号</span>
                      </a-menu-item>
                    </a-menu>
                  </template>
                </a-dropdown>
              </div>

              <div class="media-card__tags">
                <span class="badge-status" :class="`badge-status--${healthColor(account.health)}`">
                  <span class="indicator-dot"></span>
                  {{ healthLabel(account.health) }}
                </span>

                <span
                  class="badge-status"
                  :class="`badge-status--${publishStateColor(account.publishState)}`"
                >
                  <span class="indicator-dot"></span>
                  {{ publishStateLabel(account.publishState) }}
                </span>
              </div>

              <!-- Client mapping connection card -->
              <div class="media-card__client-info">
                <div class="client-info-inner">
                  <span class="client-label">运行节点</span>
                  <a-tooltip :title="clientStatusText(account)" placement="top">
                    <span
                      class="client-value"
                      :class="`client-value--${clientStatusColor(account)}`"
                    >
                      {{ clientStatusText(account) }}
                    </span>
                  </a-tooltip>
                </div>
              </div>

              <div class="media-card__meta-box">
                <div class="meta-box-item">
                  <span class="meta-label">安全校验</span>
                  <span class="meta-value">
                    {{ account.verifiedAt ? formatDateTime(account.verifiedAt) : '--' }}
                  </span>
                </div>
                <div class="meta-box-item">
                  <span class="meta-label">节点心跳</span>
                  <span class="meta-value">
                    {{ account.clientLastSeenAt ? formatDateTime(account.clientLastSeenAt) : '--' }}
                  </span>
                </div>
              </div>

              <!-- Foot note panel -->
              <div
                v-if="account.deleteRequestedAt || account.publishHint"
                class="media-card__footer"
              >
                <div v-if="account.deleteRequestedAt" class="footer-alert footer-alert--warning">
                  <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
                    <path
                      d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"
                    />
                  </svg>
                  <span>已申请解绑，可完成服务端解绑</span>
                </div>
                <div v-else-if="account.publishHint" class="footer-alert">
                  <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
                    <path
                      d="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"
                    />
                  </svg>
                  <span :title="account.publishHint">{{ account.publishHint }}</span>
                </div>
              </div>
            </article>
          </section>
        </a-spin>
      </section>
    </template>

    <!-- Custom Account Unbind Modal -->
    <a-modal
      v-model:open="unbindModalOpen"
      :destroy-on-close="true"
      :footer="null"
      :width="480"
      class="premium-unbind-modal"
      :closable="true"
    >
      <div class="unbind-modal-header">
        <div class="unbind-warning-icon-wrapper">
          <DeleteOutlined class="unbind-warning-icon" />
        </div>
        <h3 class="unbind-modal-title">解绑此运行节点上的媒体账号</h3>
        <p class="unbind-modal-subtitle">
          只解除当前卡片对应的运行节点绑定，同一平台账号在其他节点上的绑定不受影响。
        </p>
      </div>

      <div class="unbind-account-preview" v-if="unbindAccountTarget">
        <div class="preview-avatar-wrapper">
          <img
            v-if="unbindAccountTarget.avatarUrl"
            :src="unbindAccountTarget.avatarUrl"
            class="preview-avatar"
          />
          <span
            v-else
            class="preview-avatar-placeholder"
            :style="{ background: unbindAccountTarget.platformAccent }"
          >
            {{ accountInitial(unbindAccountTarget) }}
          </span>
          <img
            v-if="unbindAccountTarget.platformLogoUrl"
            :src="unbindAccountTarget.platformLogoUrl"
            class="preview-platform-icon"
          />
        </div>
        <div class="preview-info">
          <span class="preview-name">{{ unbindAccountTarget.displayName }}</span>
          <span class="preview-meta">
            {{ unbindAccountTarget.platformLabel }} · ID: {{ unbindAccountTarget.platformUid }}
          </span>
          <span class="preview-meta">
            运行节点 · {{ unbindAccountTarget.clientDeviceName || '未命名客户端' }}
          </span>
        </div>
        <div class="preview-status">
          <span
            class="badge-status"
            :class="`badge-status--${unbindAccountTarget.clientOnline ? 'success' : 'warning'}`"
          >
            <span class="indicator-dot"></span>
            {{ unbindAccountTarget.clientOnline ? '在线' : '离线' }}
          </span>
        </div>
      </div>

      <div class="unbind-consequences" v-if="unbindAccountTarget">
        <div class="consequence-item">
          <div class="consequence-icon-wrapper">
            <ExclamationCircleOutlined />
          </div>
          <div class="consequence-text">
            <strong>解除节点绑定</strong>：系统服务端将移除此运行节点上的账号映射，这张卡片不再接收发布任务。
          </div>
        </div>
        <div class="consequence-item">
          <div class="consequence-icon-wrapper">
            <LockOutlined />
          </div>
          <div class="consequence-text">
            <strong>处理本地会话</strong>：
            <span v-if="unbindAccountTarget.clientOnline">
              在线客户端同步后会清理当前节点的本地会话缓存。
            </span>
            <span v-else>
              当前运行节点离线，服务端仍会立即完成解绑；该节点下次同步时会清理本地会话缓存。
            </span>
          </div>
        </div>
        <div class="consequence-item">
          <div class="consequence-icon-wrapper">
            <CloseCircleOutlined />
          </div>
          <div class="consequence-text">
            <strong>取消排队发布</strong>：发往此运行节点此账号的等待发布任务会被取消，其他节点上的同账号任务不受影响。
          </div>
        </div>
      </div>

      <div class="unbind-verification" v-if="unbindAccountTarget">
        <div class="verification-label">
          请输入账号名称 <span class="highlight-name">{{ unbindAccountTarget.displayName }}</span> 或输入 <span class="highlight-keyword">解绑</span> 进行确认：
        </div>
        <a-input
          v-model:value="unbindVerifyInput"
          placeholder="请输入名称或“解绑”"
          class="unbind-input"
          @pressEnter="handleConfirmUnbind"
        />
      </div>

      <div class="unbind-modal-footer">
        <a-button @click="unbindModalOpen = false" class="btn-cancel">取消</a-button>
        <a-button
          type="primary"
          danger
          :disabled="!isUnbindVerified"
          :loading="unbindConfirmLoading"
          @click="handleConfirmUnbind"
          class="btn-confirm"
        >
          确认解绑
        </a-button>
      </div>
    </a-modal>

    <a-modal
      v-model:open="enterpriseSiteModalOpen"
      :title="enterpriseSiteModalTitle"
      :destroy-on-close="true"
      :ok-text="enterpriseSiteModalOkText"
      cancel-text="取消"
      :confirm-loading="saveEnterpriseSiteMutation.isPending.value"
      @ok="saveEnterpriseSiteMutation.mutate()"
      @cancel="closeEnterpriseSiteModal"
    >
      <div class="enterprise-site-form">
        <div class="form-field">
          <span>CMS 类型</span>
          <a-select
            v-model:value="enterpriseSiteForm.cmsType"
            :disabled="editingEnterpriseSiteId !== null"
            :options="cmsTypeOptions"
            :get-popup-container="getEnterpriseSiteSelectPopupContainer"
            popup-class-name="enterprise-site-cms-dropdown"
            @change="handleEnterpriseSiteCMSTypeChange"
          />
        </div>

        <label class="form-field">
          <span>站点名称</span>
          <a-input v-model:value="enterpriseSiteForm.name" placeholder="例如：品牌官网" />
        </label>

        <label class="form-field">
          <span>站点域名</span>
          <a-input
            v-model:value="enterpriseSiteForm.siteUrl"
            placeholder="https://www.example.com"
          />
        </label>

        <label class="form-field">
          <span>{{ enterpriseSiteAppIDLabel }}</span>
          <a-input
            v-model:value="enterpriseSiteForm.appid"
            :placeholder="enterpriseSiteAppIDPlaceholder"
          />
        </label>

        <label class="form-field">
          <span>Secret</span>
          <a-input-password
            v-model:value="enterpriseSiteForm.secret"
            :placeholder="enterpriseSiteSecretPlaceholder"
          />
        </label>

        <div
          class="enterprise-form-grid"
          :class="{ 'enterprise-form-grid--wordpress': enterpriseSiteForm.cmsType === 'wordpress' }"
        >
          <template v-if="enterpriseSiteForm.cmsType !== 'wordpress'">
            <label class="form-field">
              <span>默认语言</span>
              <a-input v-model:value="enterpriseSiteForm.defaultAcode" placeholder="cn" />
            </label>
            <label class="form-field">
              <span>模型编码</span>
              <a-input v-model:value="enterpriseSiteForm.defaultMcode" placeholder="2" />
            </label>
          </template>
          <label class="form-field">
            <span>{{ enterpriseSiteDefaultScodeLabel }}</span>
            <a-input
              v-model:value="enterpriseSiteForm.defaultScode"
              :placeholder="enterpriseSiteDefaultScodePlaceholder"
            />
          </label>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<style scoped>
/* Page Layout */
.media-view {
  display: flex;
  flex-direction: column;
  gap: 24px;
  background-color: #f8fafc;
  min-height: 100%;
}

/* Premium Dark Banner Section */
.media-view__top-card {
  position: relative;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  overflow: hidden;
  padding: 0;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.04);
}

.media-view__header {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 32px;
  z-index: 2;
}

.media-view__header-title {
  max-width: 650px;
}

.media-view__header-title h2 {
  margin: 0;
  font-size: 24px;
  font-weight: 700;
  color: #0f172a;
  line-height: 1.3;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  letter-spacing: 0;
}

.media-view__header-title p {
  margin: 8px 0 0;
  font-size: 13.5px;
  color: #475569;
  line-height: 1.6;
  font-weight: 400;
}

.media-view__header-actions {
  display: flex;
  gap: 12px;
}

/* Premium Refresh Button Override */
:deep(.btn-refresh.ant-btn) {
  background: #ffffff;
  border: 1px solid #e2e8f0;
  color: #0f172a;
  border-radius: 8px;
  height: 40px;
  padding: 0 18px;
  font-weight: 500;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 2px 4px rgba(148, 163, 184, 0.05);
}

:deep(.btn-refresh.ant-btn:hover) {
  background: #f8fafc;
  border-color: #cbd5e1;
  color: #1d4ed8;
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(148, 163, 184, 0.08);
}

.media-scope-tabs {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  background: #f1f5f9;
  padding: 4px;
  border-radius: 10px;
  margin: 0 32px 24px;
  border: 1px solid rgba(148, 163, 184, 0.08);
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.03);
}

.media-scope-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 38px;
  padding: 0 18px;
  border: none;
  border-radius: 7px;
  background: transparent;
  color: #64748b;
  font-size: 13.5px;
  font-weight: 550;
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  white-space: nowrap;
}

.media-scope-tab .tab-icon {
  font-size: 14px;
  color: #94a3b8;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.media-scope-tab small {
  color: #94a3b8;
  font-size: 11px;
  font-weight: 500;
  background: rgba(148, 163, 184, 0.06);
  padding: 2px 6px;
  border-radius: 4px;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.media-scope-tab:hover {
  color: #334155;
}

.media-scope-tab:hover .tab-icon {
  color: #64748b;
}

.media-scope-tab--active {
  background: #ffffff;
  color: #0f172a;
  font-weight: 600;
  box-shadow:
    0 1px 3px rgba(0, 0, 0, 0.05),
    0 4px 12px rgba(15, 23, 42, 0.04);
}

.media-scope-tab--active .tab-icon {
  color: #1677ff;
}

.media-scope-tab--active small {
  color: #1677ff;
  background: #e6f4ff;
  font-weight: 500;
}

/* Metrics strip styling */
.overview-strip {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: rgba(255, 255, 255, 0.4);
  backdrop-filter: blur(12px);
  border-top: 1px solid #e2e8f0;
  z-index: 2;
}

.overview-chip {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 24px 32px;
  border-right: 1px solid #e2e8f0;
  transition: all 0.25s ease;
}

.overview-chip:last-child {
  border-right: none;
}

.overview-chip:hover {
  background: rgba(255, 255, 255, 0.7);
}

.chip-icon-box {
  width: 42px;
  height: 42px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* Metric colored boxes styling */
.total-bg {
  background: #dbeafe;
  color: #1d4ed8;
  border: 1px solid #bfdbfe;
}

.live-bg {
  background: #d1fae5;
  color: #059669;
  border: 1px solid #a7f3d0;
}

.queued-bg {
  background: #fef3c7;
  color: #d97706;
  border: 1px solid #fde68a;
}

.attention-bg {
  background: #ffe4e6;
  color: #e11d48;
  border: 1px solid #fecdd3;
}

.chip-copy {
  display: flex;
  flex-direction: column;
}

.chip-copy span {
  color: #64748b;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
}

.chip-copy strong {
  color: #0f172a;
  font-size: 26px;
  font-weight: 700;
  margin-top: 4px;
  line-height: 1;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  letter-spacing: 0;
}

/* Panel Layout Styling */
.panel {
  background: #ffffff;
  border-radius: 8px;
  padding: 32px;
  border: 1px solid #e2e8f0;
  box-shadow: 0 4px 20px rgba(148, 163, 184, 0.05);
  transition:
    box-shadow 0.3s ease,
    border-color 0.3s ease;
}

.panel:hover {
  box-shadow: 0 10px 30px rgba(148, 163, 184, 0.08);
}

.panel-title {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  color: #0f172a;
  letter-spacing: 0;
}

.panel-desc {
  margin: 6px 0 0;
  color: #64748b;
  font-size: 13.5px;
  line-height: 1.5;
}

/* Client download header and grid */
.client-download-panel {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.client-download-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.title-with-badge {
  display: flex;
  align-items: center;
  gap: 12px;
}

.badge-pulsing-stable {
  background: rgba(37, 99, 235, 0.1);
  color: #1d4ed8;
  border: 1px solid rgba(37, 99, 235, 0.2);
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 8px;
  text-transform: uppercase;
  letter-spacing: 0;
  position: relative;
  overflow: hidden;
}

.badge-pulsing-stable::after {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(37, 99, 235, 0.18), transparent);
  animation: shine-sweep 3s infinite linear;
}

@keyframes shine-sweep {
  0% {
    left: -100%;
  }
  100% {
    left: 100%;
  }
}

.client-download-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 18px;
}

/* Client download cards */
.client-download-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 200px;
  padding: 24px;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
}

.client-download-card:hover {
  transform: translateY(-4px);
  border-color: #cbd5e1;
  box-shadow: 0 12px 24px rgba(148, 163, 184, 0.12);
}

.client-download-card__body {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}

/* Elegant custom OS SVGs logos wrapper */
.client-download-card__logo {
  width: 48px;
  height: 48px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: all 0.3s ease;
}

.logo-darwin {
  background: #0f172a;
  color: #ffffff;
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.15);
}

.logo-win32 {
  background: #0078d4;
  color: #ffffff;
  box-shadow: 0 4px 12px rgba(0, 120, 212, 0.2);
}

.logo-default,
.logo-linux {
  background: #1e293b;
  color: #38bdf8;
  box-shadow: 0 4px 12px rgba(30, 41, 59, 0.2);
}

.os-svg-icon {
  width: 22px;
  height: 22px;
}

.client-download-card__content {
  min-width: 0;
}

.client-download-card__content h4 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: #0f172a;
  line-height: 1.3;
}

.meta-inline {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
  color: #64748b;
  font-size: 12px;
}

.version-tag {
  background: #f1f5f9;
  color: #475569;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 4px;
}

.dot-separator {
  color: #cbd5e1;
  font-size: 8px;
}

/* Code-looking filename strip */
.client-download-card__file {
  display: flex;
  align-items: center;
  gap: 8px;
  background: #f1f5f9;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 10px 12px;
  margin-top: 18px;
  margin-bottom: 18px;
  overflow: hidden;
}

.file-icon {
  color: #64748b;
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.file-name {
  color: #334155;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 11.5px;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.client-download-card__actions {
  display: flex;
}

/* Download Button styling */
:deep(.btn-download.ant-btn-primary) {
  background: #1d4ed8;
  border-color: #1d4ed8;
  border-radius: 8px;
  height: 38px;
  width: 100%;
  font-weight: 600;
  font-size: 13px;
  box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2);
  transition: all 0.25s ease;
}

:deep(.btn-download.ant-btn-primary:hover:not(:disabled)) {
  background: #1e40af;
  border-color: #1e40af;
  box-shadow: 0 6px 18px rgba(37, 99, 235, 0.26);
  transform: translateY(-1px);
}

:deep(.btn-download.ant-btn-primary:disabled) {
  background: #cbd5e1;
  border-color: #cbd5e1;
  color: #94a3b8;
  box-shadow: none;
}

.enterprise-panel {
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.enterprise-panel__main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 24px;
  align-items: start;
}

.section-kicker {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 0 8px;
  border-radius: 6px;
  background: #eef2ff;
  color: #1e3a8a;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: uppercase;
}

.enterprise-panel__copy h3 {
  margin: 12px 0 0;
  color: #0f172a;
  font-size: 22px;
  font-weight: 760;
  line-height: 1.25;
}

.enterprise-panel__copy p {
  max-width: 660px;
  margin: 8px 0 0;
  color: #475569;
  font-size: 13.5px;
  line-height: 1.7;
}

.enterprise-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

:deep(.btn-enterprise-primary.ant-btn-primary) {
  height: 40px;
  border-radius: 8px;
  background: #1d4ed8;
  border-color: #1d4ed8;
  font-weight: 650;
  box-shadow: none;
}

:deep(.btn-enterprise-primary.ant-btn-primary:hover) {
  background: #1e40af;
  border-color: #1e40af;
  transform: translateY(-1px);
}

:deep(.btn-enterprise-secondary.ant-btn) {
  height: 40px;
  border-radius: 8px;
  border-color: #cbd5e1;
  color: #334155;
  font-weight: 650;
}

.enterprise-flow {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  overflow: hidden;
}

.enterprise-step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 14px;
  min-height: 108px;
  padding: 18px;
  background: #ffffff;
  border-right: 1px solid #e2e8f0;
}

.enterprise-step--action {
  cursor: pointer;
  transition:
    background 0.2s ease,
    box-shadow 0.2s ease;
}

.enterprise-step--action:hover {
  background: #eff6ff;
  box-shadow: inset 0 0 0 1px #93c5fd;
}

.enterprise-step:last-child {
  border-right: 0;
}

.enterprise-step__index {
  color: #1d4ed8;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 12px;
  font-weight: 800;
}

.enterprise-step h4 {
  margin: 0;
  color: #0f172a;
  font-size: 14px;
  font-weight: 720;
}

.enterprise-step p {
  margin: 6px 0 0;
  color: #64748b;
  font-size: 12.5px;
  line-height: 1.55;
}

.enterprise-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(360px, 0.85fr);
  gap: 24px;
}

.enterprise-grid--single {
  grid-template-columns: 1fr;
  width: 100%;
}

.connector-panel,
.adapter-panel {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.panel-head-compact {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.connector-empty-premium {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 48px 24px;
  border: 1px dashed #cbd5e1;
  border-radius: 16px;
  background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(148, 163, 184, 0.02);
}

.empty-glow {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 240px;
  height: 240px;
  background: radial-gradient(circle, rgba(37, 99, 235, 0.05) 0%, transparent 70%);
  z-index: 1;
  pointer-events: none;
}

.empty-icon-wrapper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  border-radius: 20px;
  background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
  color: #2563eb;
  margin-bottom: 20px;
  border: 1px solid rgba(37, 99, 235, 0.1);
  box-shadow: 0 8px 16px -4px rgba(37, 99, 235, 0.1);
  z-index: 2;
}

.empty-globe {
  font-size: 32px;
}

.empty-plus {
  position: absolute;
  bottom: -4px;
  right: -4px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #2563eb;
  color: #ffffff;
  font-size: 10px;
  border: 2px solid #ffffff;
  box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2);
}

.connector-empty-premium h3 {
  font-size: 18px;
  font-weight: 700;
  color: #0f172a;
  margin: 0 0 8px;
  z-index: 2;
}

.connector-empty-premium p {
  max-width: 480px;
  font-size: 13.5px;
  line-height: 1.6;
  color: #64748b;
  margin: 0 0 24px;
  z-index: 2;
}

.btn-empty-add.ant-btn {
  height: 40px;
  border-radius: 8px;
  padding: 0 24px;
  font-weight: 600;
  background: #2563eb;
  border-color: #2563eb;
  box-shadow: 0 4px 12px rgba(37, 99, 235, 0.2);
  transition: all 0.2s ease;
  z-index: 2;
}

.btn-empty-add.ant-btn:hover {
  background: #1d4ed8;
  border-color: #1d4ed8;
  box-shadow: 0 6px 16px rgba(37, 99, 235, 0.3);
  transform: translateY(-1px);
}

.site-connection-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
  gap: 24px;
  width: 100%;
}

.site-connection-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 16px;
  padding: 24px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
  box-shadow:
    0 4px 6px -1px rgba(0, 0, 0, 0.02),
    0 2px 4px -1px rgba(0, 0, 0, 0.01);
}

.site-connection-card:hover {
  border-color: #cbd5e1;
  box-shadow:
    0 20px 25px -5px rgba(15, 23, 42, 0.08),
    0 10px 10px -5px rgba(15, 23, 42, 0.04);
  transform: translateY(-4px);
}

.site-card-accent {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
}

.site-card-accent.accent-connected {
  background: linear-gradient(90deg, #10b981, #059669);
}

.site-card-accent.accent-error {
  background: linear-gradient(90deg, #f43f5e, #e11d48);
}

.site-card-accent.accent-disabled {
  background: linear-gradient(90deg, #94a3b8, #64748b);
}

.site-card-accent.accent-pending {
  background: linear-gradient(90deg, #f59e0b, #d97706);
}

.site-connection-card__header {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 20px;
}

.site-connection-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 12px;
  background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
  color: #2563eb;
  font-size: 22px;
  border: 1px solid rgba(37, 99, 235, 0.1);
  flex-shrink: 0;
}

.site-connection-card__favicon {
  width: 24px;
  height: 24px;
  border-radius: 4px;
  object-fit: contain;
}

.site-connection-card__header-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.site-name-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.site-connection-card h4 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: #0f172a;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.site-badge {
  font-size: 11px;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 6px;
  line-height: 1.4;
}

.site-badge--cms {
  background: #eff6ff;
  color: #1e40af;
  border: 1px solid #bfdbfe;
}

.site-badge--status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: fit-content;
}

.site-badge__dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}

.site-badge--status-connected {
  background: rgba(16, 185, 129, 0.08);
  color: #059669;
  border: 1px solid rgba(16, 185, 129, 0.15);
}

.site-badge--status-connected .site-badge__dot {
  background: #10b981;
  box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2);
  animation: pulse-dot-green 2s infinite;
}

@keyframes pulse-dot-green {
  0% {
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
  }
  70% {
    box-shadow: 0 0 0 6px rgba(16, 185, 129, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
  }
}

.site-badge--status-error {
  background: rgba(244, 63, 94, 0.08);
  color: #e11d48;
  border: 1px solid rgba(244, 63, 94, 0.15);
}

.site-badge--status-error .site-badge__dot {
  background: #f43f5e;
  box-shadow: 0 0 0 2px rgba(244, 63, 94, 0.2);
  animation: pulse-dot-red 2s infinite;
}

@keyframes pulse-dot-red {
  0% {
    box-shadow: 0 0 0 0 rgba(244, 63, 94, 0.7);
  }
  70% {
    box-shadow: 0 0 0 6px rgba(244, 63, 94, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(244, 63, 94, 0);
  }
}

.site-badge--status-disabled {
  background: rgba(100, 116, 139, 0.08);
  color: #475569;
  border: 1px solid rgba(100, 116, 139, 0.15);
}

.site-badge--status-disabled .site-badge__dot {
  background: #64748b;
}

.site-badge--status-pending {
  background: rgba(245, 158, 11, 0.08);
  color: #d97706;
  border: 1px solid rgba(245, 158, 11, 0.15);
}

.site-badge--status-pending .site-badge__dot {
  background: #f59e0b;
}

.site-url-box {
  background: #f8fafc;
  border: 1px solid #f1f5f9;
  border-radius: 8px;
  padding: 8px 12px;
  margin-bottom: 16px;
}

.site-link {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #64748b;
  font-size: 13px;
  transition: color 0.2s ease;
}

.site-link:hover {
  color: #2563eb;
}

.site-link .link-icon {
  color: #94a3b8;
  transition: color 0.2s ease;
}

.site-link:hover .link-icon {
  color: #2563eb;
}

.site-meta-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 20px;
}

.meta-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.meta-cell.full-width {
  grid-column: span 2;
}

.meta-cell .meta-label {
  font-size: 11px;
  color: #94a3b8;
  font-weight: 500;
}

.meta-cell .meta-value {
  font-size: 12.5px;
  color: #475569;
  font-weight: 600;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

.site-connection-card__footer-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-top: 1px solid #f1f5f9;
  padding-top: 16px;
  margin-top: auto;
}

.footer-actions-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.btn-action-ping.ant-btn,
.btn-action-sync.ant-btn {
  height: 32px;
  border-radius: 6px;
  font-size: 12.5px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-color: #cbd5e1;
  color: #475569;
  background: #ffffff;
  transition: all 0.2s ease;
}

.btn-action-ping.ant-btn:hover,
.btn-action-sync.ant-btn:hover {
  border-color: #2563eb;
  color: #2563eb;
  background: #eff6ff;
}

.action-more-btn.ant-btn-text {
  height: 32px;
  width: 32px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #64748b;
  border: 1px solid #cbd5e1;
  background: #ffffff;
  transition: all 0.2s ease;
}

.action-more-btn.ant-btn-text:hover {
  color: #0f172a;
  background: #f1f5f9;
}

.site-connection-card__error-banner {
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid #fecdd3;
  border-left: 4px solid #f43f5e;
  border-radius: 8px;
  background: #fff5f5;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.connector-sample {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-left: 3px solid #475569;
  border-radius: 8px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 16px;
}

.connector-sample__line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0;
  border-bottom: none;
}

.connector-sample__line span {
  color: #475569;
  font-size: 12px;
  font-weight: 600;
  background: #e2e8f0;
  padding: 2px 8px;
  border-radius: 4px;
  flex-shrink: 0;
}

.connector-sample__line strong {
  color: #0f172a;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 12px;
  font-weight: 600;
  overflow-wrap: anywhere;
  text-align: right;
  background: rgba(15, 23, 42, 0.03);
  padding: 3px 8px;
  border-radius: 5px;
  border: 1px solid rgba(15, 23, 42, 0.05);
}

.adapter-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.adapter-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 14px 16px;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  background: #ffffff;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.adapter-row:hover {
  border-color: #cbd5e1;
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.03);
  transform: translateY(-1px);
}

.adapter-row__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  transition: all 0.2s ease;
}

.adapter-row--ready .adapter-row__mark {
  background: #f0fdf4;
  color: #16a34a;
  border: 1px solid #dcfce7;
}

.adapter-row--planned {
  background: #fafafb;
  border-style: dashed;
}

.adapter-row--planned .adapter-row__mark {
  background: #f1f5f9;
  color: #64748b;
  border: 1px solid #e2e8f0;
}

.adapter-row__body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.adapter-row__body strong {
  color: #0f172a;
  font-size: 14px;
  font-weight: 600;
}

.adapter-row__body span {
  color: #64748b;
  font-size: 12px;
  line-height: 1.4;
}

.enterprise-site-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding-top: 4px;
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.form-field span {
  color: #334155;
  font-size: 13px;
  font-weight: 650;
}

.enterprise-form-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}

.enterprise-form-grid--wordpress {
  grid-template-columns: 1fr;
}

.enterprise-publish-hint {
  padding: 10px 12px;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  background: #eff6ff;
  color: #1e40af;
  font-size: 12.5px;
  line-height: 1.5;
}

.enterprise-publish-hint--warning {
  border-color: #fde68a;
  background: #fffbeb;
  color: #92400e;
}

:global(.enterprise-site-cms-dropdown) {
  z-index: 1100;
}

/* Spinners, alerts, empty state styling */
.premium-alert {
  border-radius: 12px;
  border: 1px solid #fecaca;
  background: #fef2f2;
}

.premium-empty {
  padding: 40px 0;
  border: 1px dashed #e2e8f0;
  border-radius: 8px;
}

/* Media list panel & search toolbar */
.media-list-panel {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.media-list-header-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
  flex-wrap: wrap;
}

.media-list-title-box {
  flex: 1;
  min-width: 250px;
}

.media-list-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* Styled Inputs & Selects */
:deep(.media-search.ant-input-affix-wrapper) {
  width: 320px;
  height: 40px;
  border-radius: 8px;
  border-color: #cbd5e1;
  background-color: #ffffff;
  padding-left: 12px;
  transition: all 0.2s ease;
}

:deep(.media-search.ant-input-affix-wrapper:hover) {
  border-color: #94a3b8;
}

:deep(.media-search.ant-input-affix-wrapper-focused) {
  border-color: #1d4ed8;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.14);
}

:deep(.media-select.ant-select .ant-select-selector) {
  height: 40px !important;
  border-radius: 8px !important;
  border-color: #cbd5e1 !important;
  padding: 4px 12px !important;
  transition: all 0.2s ease;
}

:deep(.media-select.ant-select:hover .ant-select-selector) {
  border-color: #94a3b8 !important;
}

:deep(.media-select.ant-select-focused .ant-select-selector) {
  border-color: #1d4ed8 !important;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.14) !important;
}

/* Media Card Grid */
.media-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(295px, 1fr));
  gap: 20px;
}

/* Premium Media Card */
.media-card {
  position: relative;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(148, 163, 184, 0.03);
}

.media-card__accent-bar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  opacity: 0.85;
}

.media-card:hover {
  transform: translateY(-5px);
  border-color: #cbd5e1;
  box-shadow: 0 16px 36px rgba(148, 163, 184, 0.12);
}

.media-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.media-card__identity {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
  flex: 1;
}

.media-card__more.ant-btn-text {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 50%;
  color: #64748b;
  background: transparent;
  border: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: all 0.2s ease;
}

.media-card__more.ant-btn-text:hover,
.media-card__more.ant-btn-text:focus {
  color: #0f172a;
  background: #f1f5f9;
  border: none;
}

/* Circular Avatar glow container */
.media-card__avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
  background: #f1f5f9;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  transition: transform 0.3s ease;
}

.media-card:hover .media-card__avatar {
  transform: scale(1.05);
}

.media-card__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar-initial {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #ffffff;
  font-weight: 700;
  font-size: 16px;
}

.media-card__identity-copy {
  min-width: 0;
  flex: 1;
}

.media-card__identity-copy h3 {
  margin: 0;
  color: #0f172a;
  font-size: 15.5px;
  font-weight: 700;
  line-height: 1.3;
  display: flex;
  align-items: center;
  gap: 6px;
}

.platform-logo-container {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
}

.media-card__inline-platform-icon {
  width: 16px;
  height: 16px;
  object-fit: contain;
}

.media-card__inline-platform-text {
  font-size: 10px;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 4px;
  letter-spacing: 0;
}

.media-card__identity-copy p {
  margin: 5px 0 0;
  color: #64748b;
  font-size: 12.5px;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.media-card__platform-name {
  font-weight: 600;
  color: #475569;
}

.media-card__uid-divider {
  color: #cbd5e1;
  font-weight: bold;
}

.media-card__uid {
  color: #94a3b8;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 11px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}

/* Polished Pill Badges */
.media-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
}

.badge-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 8px;
  line-height: 1.4;
}

.indicator-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  display: inline-block;
}

/* Colorful status mapping */
.badge-status--green {
  background: rgba(16, 185, 129, 0.08);
  color: #059669;
  border: 1px solid rgba(16, 185, 129, 0.15);
}
.badge-status--green .indicator-dot {
  background-color: #10b981;
}

.badge-status--orange {
  background: rgba(245, 158, 11, 0.08);
  color: #d97706;
  border: 1px solid rgba(245, 158, 11, 0.15);
}
.badge-status--orange .indicator-dot {
  background-color: #f59e0b;
}

.badge-status--gold {
  background: rgba(217, 119, 6, 0.08);
  color: #b45309;
  border: 1px solid rgba(217, 119, 6, 0.15);
}
.badge-status--gold .indicator-dot {
  background-color: #d97706;
}

.badge-status--red {
  background: rgba(244, 63, 94, 0.08);
  color: #e11d48;
  border: 1px solid rgba(244, 63, 94, 0.15);
}
.badge-status--red .indicator-dot {
  background-color: #f43f5e;
}

.badge-status--default {
  background: rgba(100, 116, 139, 0.08);
  color: #475569;
  border: 1px solid rgba(100, 116, 139, 0.15);
}
.badge-status--default .indicator-dot {
  background-color: #64748b;
}

/* Client runtime block */
.media-card__client-info {
  background: #f8fafc;
  border: 1px solid #f1f5f9;
  border-radius: 8px;
  padding: 10px 12px;
}

.client-info-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
}

.client-label {
  color: #64748b;
  font-weight: 500;
}

.client-value {
  font-weight: 600;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.client-value--green {
  color: #059669;
}

.client-value--gold {
  color: #d97706;
}

.client-value--default {
  color: #64748b;
}

/* Metadata box */
.media-card__meta-box {
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-top: 1px solid #f1f5f9;
  padding-top: 12px;
}

.meta-box-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11.5px;
}

.meta-label {
  color: #94a3b8;
  font-weight: 500;
}

.meta-value {
  color: #475569;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-weight: 500;
}

/* Card footer details hints */
.media-card__footer {
  margin-top: auto;
  border-top: 1px dashed #f1f5f9;
  padding-top: 12px;
}

.footer-alert {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: #64748b;
  background: #f8fafc;
  border-radius: 6px;
  padding: 6px 10px;
  line-height: 1.4;
}

.footer-alert svg {
  flex-shrink: 0;
  color: #94a3b8;
}

.footer-alert span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.footer-alert--warning {
  background: #fffbeb;
  color: #b45309;
  border: 1px solid #fef3c7;
}

.footer-alert--warning svg {
  color: #d97706;
}

/* Responsiveness adjustments */
@media (max-width: 1024px) {
  .enterprise-panel__main,
  .enterprise-grid {
    grid-template-columns: 1fr;
  }

  .enterprise-actions {
    justify-content: flex-start;
  }

  .enterprise-flow {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .enterprise-step:nth-child(2) {
    border-right: 0;
  }

  .enterprise-step:nth-child(-n + 2) {
    border-bottom: 1px solid #e2e8f0;
  }

  .overview-strip {
    grid-template-columns: repeat(2, 1fr);
  }

  .overview-chip {
    border-bottom: 1px solid #e2e8f0;
  }

  .overview-chip:nth-child(even) {
    border-right: none;
  }

  .overview-chip:nth-child(n + 3) {
    border-bottom: none;
  }
}

@media (max-width: 768px) {
  .media-view__header {
    flex-direction: column;
    align-items: stretch;
    gap: 20px;
    padding: 24px;
  }

  .media-view__header-actions {
    width: 100%;
  }

  .media-view__header-actions :deep(.ant-btn) {
    width: 100%;
  }

  .media-scope-tabs {
    margin: 0 24px 20px;
    display: flex;
    padding: 4px;
  }

  .media-scope-tab {
    flex: 1;
    min-width: 0;
    justify-content: center;
  }

  .site-connection-grid {
    grid-template-columns: 1fr;
  }

  .overview-chip {
    padding: 16px 20px;
  }

  .panel {
    padding: 20px;
  }

  .media-list-header-row {
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
  }

  .media-list-toolbar {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }

  :deep(.media-search.ant-input-affix-wrapper) {
    width: 100%;
  }

  :deep(.media-select.ant-select) {
    width: 100% !important;
  }

  .enterprise-flow {
    grid-template-columns: 1fr;
  }

  .enterprise-step,
  .enterprise-step:nth-child(2) {
    border-right: 0;
    border-bottom: 1px solid #e2e8f0;
  }

  .enterprise-step:last-child {
    border-bottom: 0;
  }

  .connector-empty {
    align-items: flex-start;
  }

  .connector-sample__line,
  .adapter-row {
    grid-template-columns: 1fr;
  }

  .enterprise-form-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 480px) {
  .overview-strip {
    grid-template-columns: 1fr;
  }

  .overview-chip {
    border-right: none;
    border-bottom: 1px solid #e2e8f0;
  }

  .overview-chip:last-child {
    border-bottom: none;
  }

  .client-download-grid,
  .media-grid {
    grid-template-columns: 1fr;
  }

  .site-connection-card {
    padding: 16px;
  }

  .site-meta-grid {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .meta-cell.full-width {
    grid-column: span 1;
  }

  .site-connection-card__footer-actions {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .btn-action-ping.ant-btn {
    width: 100%;
    justify-content: center;
  }

  .footer-actions-right {
    justify-content: space-between;
    width: 100%;
  }

  .btn-action-sync.ant-btn {
    flex: 1;
    justify-content: center;
  }
}

:deep(.action-more-btn.ant-btn-text) {
  color: #64748b;
  background: transparent;
  border: 1px solid #cbd5e1;
}

:deep(.action-more-btn.ant-btn-text:hover) {
  color: #0f172a;
  background: #f1f5f9;
}

:deep(.ant-dropdown-menu-item) {
  padding: 8px 14px;
  font-size: 13.5px;
  color: #334155;
}

:deep(.ant-dropdown-menu-title-content) {
  display: flex;
  align-items: center;
  gap: 10px;
}

:deep(.ant-dropdown-menu-item .anticon) {
  font-size: 15px;
  color: #64748b;
  transition: color 0.2s ease;
}

:deep(.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-danger):hover .anticon) {
  color: #2563eb;
}

:deep(.ant-dropdown-menu-item-danger:hover .anticon) {
  color: #ffffff;
}

/* Custom Account Unbind Modal Styles */
.premium-unbind-modal :deep(.ant-modal-content) {
  border-radius: 16px;
  padding: 24px;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}

.premium-unbind-modal :deep(.ant-modal-header) {
  margin-bottom: 20px;
}

.unbind-modal-header {
  text-align: center;
  margin-bottom: 24px;
}

.unbind-warning-icon-wrapper {
  width: 56px;
  height: 56px;
  background-color: #fef2f2;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 16px;
  border: 1px solid #fee2e2;
  animation: pulse-warning 2s infinite ease-in-out;
}

@keyframes pulse-warning {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.15);
  }
  50% {
    transform: scale(1.05);
    box-shadow: 0 0 0 10px rgba(239, 68, 68, 0);
  }
}

.unbind-warning-icon {
  font-size: 24px;
  color: #ef4444;
}

.unbind-modal-title {
  font-size: 18px;
  font-weight: 700;
  color: #0f172a;
  margin: 0 0 8px;
}

.unbind-modal-subtitle {
  font-size: 13px;
  color: #64748b;
  margin: 0;
  line-height: 1.5;
}

/* Account Preview inside Modal */
.unbind-account-preview {
  display: flex;
  align-items: center;
  gap: 12px;
  background-color: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  padding: 12px 16px;
  margin-bottom: 20px;
}

.preview-avatar-wrapper {
  position: relative;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
}

.preview-avatar {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid #cbd5e1;
}

.preview-avatar-placeholder {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 600;
  font-size: 14px;
}

.preview-platform-icon {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 16px;
  height: 16px;
  background: white;
  border-radius: 50%;
  padding: 2px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.preview-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.preview-name {
  font-size: 14px;
  font-weight: 600;
  color: #1e293b;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.preview-meta {
  font-size: 12px;
  color: #64748b;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.preview-status {
  flex-shrink: 0;
}

/* Consequences List */
.unbind-consequences {
  display: flex;
  flex-direction: column;
  gap: 12px;
  background-color: #fffaf0;
  border: 1px dashed #feebc8;
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 24px;
}

.consequence-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.consequence-icon-wrapper {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 2px;
  color: #dd6b20;
}

.consequence-icon-wrapper .anticon {
  font-size: 14px;
}

.consequence-text {
  font-size: 13px;
  color: #7b341e;
  line-height: 1.5;
}

.consequence-text strong {
  color: #dd6b20;
}

/* Verification Input */
.unbind-verification {
  margin-bottom: 24px;
}

.verification-label {
  font-size: 13px;
  color: #475569;
  margin-bottom: 8px;
  line-height: 1.5;
}

.highlight-name {
  font-family: monospace;
  font-weight: 700;
  color: #ef4444;
  background-color: #fef2f2;
  padding: 2px 6px;
  border-radius: 4px;
  border: 1px solid #fee2e2;
  margin: 0 2px;
}

.highlight-keyword {
  font-weight: 700;
  color: #3b82f6;
  background-color: #eff6ff;
  padding: 2px 6px;
  border-radius: 4px;
  border: 1px solid #dbeafe;
  margin: 0 2px;
}

.unbind-input.ant-input {
  height: 40px;
  border-radius: 8px;
  border-color: #cbd5e1;
  font-size: 14px;
  transition: all 0.2s ease;
}

.unbind-input.ant-input:focus {
  border-color: #ef4444;
  box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.12);
}

/* Footer Actions */
.unbind-modal-footer {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}

.unbind-modal-footer .btn-cancel {
  height: 40px;
  border-radius: 8px;
  padding: 0 16px;
  font-size: 14px;
  font-weight: 500;
  color: #475569;
  border-color: #cbd5e1;
}

.unbind-modal-footer .btn-cancel:hover {
  color: #1e293b;
  border-color: #94a3b8;
  background: #f8fafc;
}

.unbind-modal-footer .btn-confirm {
  height: 40px;
  border-radius: 8px;
  padding: 0 20px;
  font-size: 14px;
  font-weight: 600;
}

/* Premium Dropdown styles */
:global(.premium-unbind-dropdown .ant-dropdown-menu) {
  border-radius: 12px !important;
  padding: 6px !important;
  border: 1px solid #f1f5f9 !important;
  box-shadow: 0 10px 25px -5px rgba(15, 23, 42, 0.08), 0 8px 16px -6px rgba(15, 23, 42, 0.04) !important;
}

:global(.premium-unbind-dropdown .ant-dropdown-menu-item) {
  border-radius: 8px !important;
  padding: 8px 16px !important;
  font-size: 13.5px !important;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1) !important;
}

:global(.premium-unbind-dropdown .ant-dropdown-menu-item:not(.ant-dropdown-menu-item-danger):hover) {
  background-color: #eff6ff !important;
  color: #2563eb !important;
}

:global(.premium-unbind-dropdown .ant-dropdown-menu-item:not(.ant-dropdown-menu-item-danger):hover .anticon) {
  color: #2563eb !important;
}

:global(.premium-unbind-dropdown .ant-dropdown-menu-item-danger) {
  color: #ef4444 !important;
}

:global(.premium-unbind-dropdown .ant-dropdown-menu-item-danger .anticon) {
  color: #ef4444 !important;
  font-size: 15px !important;
}

:global(.premium-unbind-dropdown .ant-dropdown-menu-item-danger:hover) {
  background-color: #fef2f2 !important;
  color: #dc2626 !important;
}

:global(.premium-unbind-dropdown .ant-dropdown-menu-item-danger:hover .anticon) {
  color: #dc2626 !important;
}
</style>
