<script setup lang="ts">
import {
  ClockCircleOutlined,
  CopyOutlined,
  DesktopOutlined,
  ExportOutlined,
  ReloadOutlined,
  RetweetOutlined,
  SearchOutlined,
  StopOutlined,
} from '@ant-design/icons-vue'
import type { PublishRecord, PublishRecordListResponse } from '@geo/shared-types'
import { useQuery } from '@tanstack/vue-query'
import type { TableColumnsType } from 'ant-design-vue'
import { message } from 'ant-design-vue'
import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'

import { publishRecordsApi, publishTasksApi } from '@/lib/api'
import { copyTextToClipboard } from '@/lib/clipboard'
import { formatDateTime } from '@/lib/display'
import { formatError, formatStoredErrorMessage } from '@/lib/errors'
import { resolvePlatformLogoUrl } from '@/lib/publish-account-cards'
import { getPublishPlatformMeta, normalizePublishPlatformId } from '@/lib/publish-platforms'

const PAGE_SIZE = 10
const INLINE_ERROR_HEAD_CHARS = 52
const INLINE_ERROR_TAIL_CHARS = 10
const ACTIVE_PUBLISH_RECORD_POLL_INTERVAL_MS = 5_000
const DONGCHEDI_PLATFORM_EXCEPTION_MESSAGE =
  '懂车帝平台返回异常，请打开懂车帝后台查看并处理平台提示，确认账号状态后再重试。'

interface PublishRecordItem {
  id: string
  recordId: number
  title: string
  articleId: number
  brandId: number
  brandName: string
  brandDeleted: boolean
  targetType: string
  platform: string
  platformName: string
  platformShortName: string
  platformAccent: string
  platformLogoUrl: string | null
  accountName: string
  status: string
  statusLabel: string
  statusColor: string
  summary: string
  createdAt: string
  updatedAt: string
  publishedAt: string | null
  externalUrl: string | null
  workbenchUrl: string | null
  desktopTaskId: string | null
  errorMessage: string | null
  canOpenWorkbench: boolean
}

function extractString(value: string | null | undefined): string | null {
  if (typeof value !== 'string') {
    return null
  }
  const trimmed = value.trim()
  return trimmed ? trimmed : null
}

function normalizeRecordStatus(status: string): string {
  const normalized = status.trim().toLowerCase()
  if (normalized === 'published' || normalized === 'publish_success') {
    return 'success'
  }
  if (normalized === 'canceled') {
    return 'cancelled'
  }
  return normalized || 'unknown'
}

function isPendingStatus(status: string): boolean {
  return status === 'queued' || status === 'publishing'
}

function hasActivePublishingRecord(page: PublishRecordListResponse | undefined): boolean {
  return Boolean(
    page?.items.some((record) => isPendingStatus(normalizeRecordStatus(record.status))),
  )
}

function normalizeRecordErrorMessage(
  messageText: string | null,
  platform?: string | null,
): string | null {
  const normalized = extractString(messageText)
  if (!normalized) {
    return null
  }
  if (
    platform === 'dongchedi' &&
    (/\bserver[\s_-]*exception\b/i.test(normalized) ||
      /\bdongchedi_platform_exception\b/i.test(normalized))
  ) {
    return DONGCHEDI_PLATFORM_EXCEPTION_MESSAGE
  }
  return formatStoredErrorMessage(normalized)
}

function inlineErrorPreview(messageText: string): string {
  const compact = messageText.replace(/\s+/g, ' ').trim()
  const maxLength = INLINE_ERROR_HEAD_CHARS + INLINE_ERROR_TAIL_CHARS + 3
  if (compact.length <= maxLength) {
    return compact
  }
  return `${compact.slice(0, INLINE_ERROR_HEAD_CHARS)}...${compact.slice(-INLINE_ERROR_TAIL_CHARS)}`
}

function summaryForRecord(record: PublishRecord, status: string): string {
  const targetLabel = record.target_type === 'enterprise_site' ? '企业站点' : '目标平台'
  switch (status) {
    case 'queued':
      return record.target_type === 'enterprise_site'
        ? '企业站发布请求已创建，等待服务端处理。'
        : '任务已进入桌面端发布队列。'
    case 'publishing':
      return record.target_type === 'enterprise_site'
        ? '服务端正在调用站点连接发文。'
        : '桌面端正在执行发送。'
    case 'success':
      return `文章已成功发送到${targetLabel}。`
    case 'failed':
      return record.target_type === 'enterprise_site'
        ? '本次企业站发布失败，请检查站点连接或发布错误。'
        : '本次发送失败，请检查账号状态或平台提示后重新提交。'
    case 'cancelled':
      return '本次发布已取消。'
    case 'unknown':
    default:
      return '发布结果异常，请检查目标侧结果。'
  }
}

function statusMetaForRecord(status: string): { label: string; color: string } {
  switch (status) {
    case 'queued':
      return { label: '等待发布', color: 'processing' }
    case 'publishing':
      return { label: '发布中', color: 'processing' }
    case 'success':
      return { label: '发布成功', color: 'success' }
    case 'failed':
      return { label: '发布失败', color: 'error' }
    case 'cancelled':
      return { label: '已取消', color: 'default' }
    case 'unknown':
      return { label: '结果异常', color: 'error' }
    default:
      return { label: status, color: 'default' }
  }
}

function isSafeHttpUrl(url: string | null): url is string {
  if (!url) {
    return false
  }
  try {
    const parsed = new URL(url)
    return parsed.protocol === 'http:' || parsed.protocol === 'https:'
  } catch {
    return false
  }
}

function buildDesktopWorkbenchUrl(record: {
  accountId: string
  platform: string
  accountName: string
}): string {
  const params = new URLSearchParams({
    action: 'open-publish-account-console',
    account_id: record.accountId,
    platform: record.platform,
    platform_uid: '',
    display_name: record.accountName,
  })
  return `shengxintui://desktop/workbench?${params.toString()}`
}

const { t } = useI18n()
const page = ref(1)
const searchTitle = ref('')
const appliedTitle = ref('')
const copiedErrorTaskId = ref<string | null>(null)
const retryingTaskId = ref<string | null>(null)
const cancelingTaskId = ref<string | null>(null)
const manualRefreshing = ref(false)

const recordsQuery = useQuery({
  queryKey: computed(() => [
    'tenant',
    'publish-records',
    { page: page.value, page_size: PAGE_SIZE, title: appliedTitle.value },
  ]),
  queryFn: () =>
    publishRecordsApi.list({
      page: page.value,
      page_size: PAGE_SIZE,
      title: appliedTitle.value || undefined,
    }),
  refetchInterval: (query) => {
    const data = query.state.data as PublishRecordListResponse | undefined
    return hasActivePublishingRecord(data) ? ACTIVE_PUBLISH_RECORD_POLL_INTERVAL_MS : false
  },
  refetchIntervalInBackground: false,
})

const loading = computed(() => recordsQuery.isPending.value)
const refreshing = computed(() => manualRefreshing.value)
const recordPage = computed(() => recordsQuery.data.value)
const pendingCount = computed(() => recordPage.value?.pending_count ?? 0)
const historyTotal = computed(() => recordPage.value?.history_total ?? 0)
const totalCount = computed(() => recordPage.value?.total ?? 0)

const publishRecords = computed<PublishRecordItem[]>(() =>
  (recordPage.value?.items ?? []).map((record) => {
    const status = normalizeRecordStatus(record.status)
    const platformId = normalizePublishPlatformId(record.platform_id)
    const platformMeta = getPublishPlatformMeta(platformId)
    const isEnterpriseSite = record.target_type === 'enterprise_site'
    const accountName =
      extractString(record.platform_nickname) ?? (isEnterpriseSite ? '企业自建站点' : '待同步账号')
    const statusMeta = statusMetaForRecord(status)
    const externalUrl =
      extractString(record.external_article_url) ?? extractString(record.external_manage_url)
    const desktopAccountId = extractString(record.desktop_account_id)
    const workbenchUrl =
      !isEnterpriseSite && desktopAccountId
        ? buildDesktopWorkbenchUrl({
            accountId: desktopAccountId,
            platform: platformId,
            accountName,
          })
        : null

    return {
      id: String(record.id),
      recordId: record.id,
      title: extractString(record.article_title) ?? `文章 #${record.article_id}`,
      articleId: record.article_id,
      brandId: record.brand_id,
      brandName: extractString(record.brand_name) ?? `公司 #${record.brand_id}`,
      brandDeleted: Boolean(record.brand_deleted),
      targetType: record.target_type ?? 'platform_account',
      platform: platformId,
      platformName: isEnterpriseSite ? '企业自建站点' : record.platform_name || platformMeta.name,
      platformShortName: platformMeta.shortName,
      platformAccent: platformMeta.accent,
      platformLogoUrl: resolvePlatformLogoUrl(platformId),
      accountName,
      status,
      statusLabel: statusMeta.label,
      statusColor: statusMeta.color,
      summary: summaryForRecord(record, status),
      createdAt: record.created_at,
      updatedAt: record.updated_at,
      publishedAt: record.published_at,
      externalUrl: isSafeHttpUrl(externalUrl) ? externalUrl : null,
      workbenchUrl,
      desktopTaskId: extractString(record.desktop_task_id),
      errorMessage: normalizeRecordErrorMessage(record.error_message, platformId),
      canOpenWorkbench: Boolean(workbenchUrl),
    }
  }),
)

const columns = computed<TableColumnsType<PublishRecordItem>>(() => [
  { title: '发文标题', key: 'title', dataIndex: 'title', width: 280, ellipsis: true },
  { title: '目标', key: 'account', dataIndex: 'account', width: 190 },
  { title: '状态', key: 'status', dataIndex: 'status', width: 110 },
  { title: '发布信息', key: 'meta', dataIndex: 'meta', width: 320 },
  { title: '时间', key: 'time', dataIndex: 'time', width: 170 },
  { title: '操作', key: 'actions', align: 'right', width: 150, fixed: 'right' },
])

watch(searchTitle, (value) => {
  if (!value.trim() && appliedTitle.value) {
    appliedTitle.value = ''
    page.value = 1
  }
})

async function refresh(): Promise<void> {
  if (manualRefreshing.value) {
    return
  }

  manualRefreshing.value = true
  try {
    await recordsQuery.refetch()
  } finally {
    manualRefreshing.value = false
  }
}

function applySearch(): void {
  page.value = 1
  appliedTitle.value = searchTitle.value.trim()
}

function handlePageChange(nextPage: number): void {
  page.value = nextPage
}

function rowClassName(record: PublishRecordItem): string {
  return isPendingStatus(record.status) ? 'publish-management-row--pending' : ''
}

function canRetryTask(record: PublishRecordItem): boolean {
  return Boolean(record.desktopTaskId && record.status === 'failed' && !record.brandDeleted)
}

function canCancelTask(record: PublishRecordItem): boolean {
  return Boolean(record.desktopTaskId && record.status === 'queued')
}

async function retryTask(record: PublishRecordItem): Promise<void> {
  if (!record.desktopTaskId) {
    return
  }
  retryingTaskId.value = record.id
  try {
    const result = await publishTasksApi.retry(record.desktopTaskId)
    const created = result.created_task_ids.length
    const existing = result.existing_task_ids.length
    const requeued = result.requeued_task_ids?.length ?? 0
    if (created > 0) {
      message.success(created === 1 ? '已创建新的发布任务' : `已创建 ${created} 个新的发布任务`)
    } else if (requeued > 0) {
      message.success(requeued === 1 ? '已重新提交发布任务' : `已重新提交 ${requeued} 个发布任务`)
    } else if (existing > 0) {
      if (record.status === 'unknown') {
        message.warning('原任务结果未知且已有发布记录，可能已成功，请先核实平台侧结果。')
      } else {
        message.info('发布任务已存在，无需重复创建')
      }
    } else {
      message.success('已提交重试请求')
    }
    await recordsQuery.refetch()
  } catch (error) {
    message.error(formatError(error))
  } finally {
    retryingTaskId.value = null
  }
}

async function cancelTask(record: PublishRecordItem): Promise<void> {
  if (!record.desktopTaskId) {
    return
  }
  cancelingTaskId.value = record.id
  try {
    await publishTasksApi.cancel(record.desktopTaskId)
    message.success('已取消等待发布任务')
    await recordsQuery.refetch()
  } catch (error) {
    message.error(formatError(error))
  } finally {
    cancelingTaskId.value = null
  }
}

async function copyErrorMessage(record: PublishRecordItem): Promise<void> {
  if (!record.errorMessage) {
    return
  }

  try {
    await copyTextToClipboard(record.errorMessage)
    copiedErrorTaskId.value = record.id
    message.success('错误详情已复制')
    window.setTimeout(() => {
      if (copiedErrorTaskId.value === record.id) {
        copiedErrorTaskId.value = null
      }
    }, 1500)
  } catch (error) {
    message.error(formatError(error))
  }
}
</script>

<template>
  <div class="publish-management-view">
    <section class="publish-management-view__top-card">
      <div class="publish-management-view__header">
        <div class="publish-management-view__header-title">
          <h2>{{ t('route.publishManagement.title') }}</h2>
          <p>{{ t('route.publishManagement.description') }}</p>
        </div>
        <div class="publish-management-view__header-actions">
          <a-button :loading="refreshing" @click="refresh">
            <template #icon><ReloadOutlined /></template>
            {{ t('common.refresh') }}
          </a-button>
        </div>
      </div>

      <div class="publish-management-view__summary">
        <div class="summary-chip">
          <span>等待发布</span>
          <strong :class="{ 'summary-chip__value--accent': pendingCount > 0 }">
            {{ pendingCount }}
          </strong>
        </div>
        <div class="summary-chip">
          <span>已发送</span>
          <strong>{{ historyTotal }}</strong>
        </div>
        <div class="summary-chip">
          <span>历史总数</span>
          <strong>{{ totalCount }}</strong>
        </div>
      </div>
    </section>

    <section class="publish-management-view__table-card">
      <div class="publish-management-view__toolbar">
        <div>
          <p class="eyebrow">Publish Records</p>
          <h3>待发布与已发布记录</h3>
        </div>
        <div class="publish-management-view__filters">
          <a-input
            v-model:value="searchTitle"
            allow-clear
            placeholder="搜索发文标题"
            class="publish-management-view__search"
            @pressEnter="applySearch"
          >
            <template #prefix>
              <SearchOutlined />
            </template>
          </a-input>
          <a-button type="primary" @click="applySearch">{{ t('common.search') }}</a-button>
        </div>
      </div>

      <a-table
        row-key="id"
        class="publish-management-table"
        :columns="columns"
        :data-source="publishRecords"
        :pagination="false"
        :loading="loading"
        :scroll="{ x: 1220 }"
        :row-class-name="rowClassName"
        :locale="{ emptyText: '暂无匹配的发文记录' }"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'title'">
            <div class="publish-cell-stack">
              <a-tooltip :title="record.title" placement="topLeft">
                <span class="publish-cell-title">{{ record.title }}</span>
              </a-tooltip>
              <span class="publish-cell-sub">
                <template v-if="record.articleId">文章 #{{ record.articleId }}</template>
                <template v-else>未关联文章</template>
              </span>
              <span class="publish-brand-line">
                <span class="publish-brand-name">{{ record.brandName }}</span>
                <a-tag v-if="record.brandDeleted" color="default" class="publish-brand-tag">
                  公司已删除
                </a-tag>
              </span>
            </div>
          </template>

          <template v-else-if="column.key === 'account'">
            <div class="publish-account-cell">
              <span class="platform-avatar" :style="{ color: record.platformAccent }">
                <img
                  v-if="record.platformLogoUrl"
                  :src="record.platformLogoUrl"
                  :alt="record.platformName"
                />
                <template v-else>{{ record.platformShortName }}</template>
              </span>
              <div class="publish-cell-stack">
                <span class="publish-cell-title publish-cell-title--compact">
                  {{ record.accountName }}
                </span>
                <span class="publish-cell-sub">{{ record.platformName }}</span>
              </div>
            </div>
          </template>

          <template v-else-if="column.key === 'status'">
            <a-tag :color="record.statusColor">{{ record.statusLabel }}</a-tag>
          </template>

          <template v-else-if="column.key === 'meta'">
            <div class="publish-cell-stack publish-meta-cell">
              <span v-if="record.errorMessage" class="publish-error-row">
                <a-popover placement="topLeft" overlay-class-name="publish-error-popover">
                  <template #content>
                    <div class="publish-error-panel" @click.stop>
                      <div class="publish-error-panel__title">发布错误</div>
                      <pre>{{ record.errorMessage }}</pre>
                      <button
                        type="button"
                        class="publish-error-panel__copy"
                        @click.stop="copyErrorMessage(record)"
                      >
                        <CopyOutlined />
                        <span>
                          {{ copiedErrorTaskId === record.id ? '已复制' : '复制错误详情' }}
                        </span>
                      </button>
                    </div>
                  </template>
                  <span class="publish-error-text">
                    {{ inlineErrorPreview(record.errorMessage) }}
                  </span>
                </a-popover>
              </span>
              <span v-else class="publish-cell-sub publish-cell-sub--strong">
                {{ record.summary }}
              </span>
              <span class="publish-meta-footer">
                <span class="attempt-chip">记录 #{{ record.recordId }}</span>
                <span class="meta-divider">·</span>
                <span>{{ record.targetType === 'enterprise_site' ? '企业站点' : '媒体账号' }}</span>
                <template v-if="record.publishedAt">
                  <span class="meta-divider">·</span>
                  <span>{{ formatDateTime(record.publishedAt) }} 发布</span>
                </template>
              </span>
            </div>
          </template>

          <template v-else-if="column.key === 'time'">
            <a-tooltip
              :title="`创建 ${formatDateTime(record.createdAt)} · 更新 ${formatDateTime(record.updatedAt)}`"
              placement="topLeft"
            >
              <div class="publish-cell-stack">
                <span class="publish-cell-title publish-cell-title--compact">
                  {{ formatDateTime(record.updatedAt) }}
                </span>
                <span class="publish-cell-sub">创建 {{ formatDateTime(record.createdAt) }}</span>
              </div>
            </a-tooltip>
          </template>

          <template v-else-if="column.key === 'actions'">
            <div class="publish-actions">
              <a-tooltip :title="record.externalUrl ? '打开外链' : '无外链'" placement="top">
                <span class="publish-action-tooltip-wrap">
                  <a-button
                    type="text"
                    class="publish-action-btn"
                    :disabled="!record.externalUrl"
                    :href="record.externalUrl || undefined"
                    :target="record.externalUrl ? '_blank' : undefined"
                    :rel="record.externalUrl ? 'noopener noreferrer' : undefined"
                    :aria-label="
                      record.externalUrl ? `打开外链：${record.title}` : `无外链：${record.title}`
                    "
                  >
                    <template #icon><ExportOutlined /></template>
                  </a-button>
                </span>
              </a-tooltip>
              <a-tooltip
                v-if="record.canOpenWorkbench"
                :title="`打开 ${record.accountName} 的${record.platformName}工作台`"
                placement="top"
              >
                <a-button
                  type="text"
                  class="publish-action-btn"
                  :href="record.workbenchUrl || undefined"
                  :aria-label="`打开 ${record.accountName} 的${record.platformName}工作台`"
                >
                  <template #icon><DesktopOutlined /></template>
                </a-button>
              </a-tooltip>
              <a-tooltip v-if="canRetryTask(record)" title="重新提交发布任务" placement="top">
                <a-button
                  type="text"
                  class="publish-action-btn"
                  :loading="retryingTaskId === record.id"
                  :aria-label="`重新提交发布任务：${record.title}`"
                  @click.stop="retryTask(record)"
                >
                  <template #icon><RetweetOutlined /></template>
                </a-button>
              </a-tooltip>
              <a-popconfirm
                v-if="canCancelTask(record)"
                title="确认取消这个等待发布任务？"
                ok-text="取消发布"
                cancel-text="保留"
                placement="topRight"
                @confirm="cancelTask(record)"
              >
                <a-tooltip title="取消发布任务" placement="top">
                  <a-button
                    type="text"
                    class="publish-action-btn publish-action-btn--danger"
                    :loading="cancelingTaskId === record.id"
                    :aria-label="`取消发布任务：${record.title}`"
                    @click.stop
                  >
                    <template #icon><StopOutlined /></template>
                  </a-button>
                </a-tooltip>
              </a-popconfirm>
              <a-tooltip v-else-if="isPendingStatus(record.status)" title="发布进行中">
                <span class="publish-action-placeholder">
                  <ClockCircleOutlined />
                </span>
              </a-tooltip>
            </div>
          </template>
        </template>
      </a-table>

      <div class="publish-management-view__pagination">
        <a-pagination
          :current="page"
          :page-size="PAGE_SIZE"
          :total="totalCount"
          :show-size-changer="false"
          @change="handlePageChange"
        />
      </div>
    </section>
  </div>
</template>

<style scoped>
.publish-management-view {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.publish-management-view__top-card,
.publish-management-view__table-card {
  background: #fff;
  border: 1px solid #e6edf5;
  border-radius: 12px;
  overflow: hidden;
}

.publish-management-view__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  padding: 24px;
}

.publish-management-view__header-title h2 {
  margin: 0;
  color: #1a1a1a;
  font-size: 20px;
  font-weight: 600;
  line-height: 1.4;
}

.publish-management-view__header-title p {
  margin: 6px 0 0;
  color: #8c8c8c;
  font-size: 13px;
  line-height: 1.7;
}

.publish-management-view__summary {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid #eef2f7;
}

.summary-chip {
  padding: 18px 24px;
  border-right: 1px solid #eef2f7;
}

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

.summary-chip span {
  display: block;
  color: #8c8c8c;
  font-size: 12px;
}

.summary-chip strong {
  display: block;
  margin-top: 8px;
  color: #1a1a1a;
  font-size: 24px;
  font-weight: 700;
}

.summary-chip__value--accent {
  color: #d48806 !important;
}

.publish-management-view__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 24px;
  border-bottom: 1px solid #f0f0f0;
}

.publish-management-view__toolbar h3 {
  margin: 0;
  color: #1a1a1a;
  font-size: 16px;
  font-weight: 700;
}

.publish-management-view__filters {
  display: flex;
  align-items: center;
  gap: 12px;
}

.publish-management-view__search {
  width: 280px;
}

.publish-management-table {
  padding: 0 24px 12px;
}

:deep(.publish-management-table .ant-table-thead > tr > th) {
  color: #6b7280;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

:deep(.publish-management-table .ant-table-tbody > tr > td) {
  padding: 15px 12px;
  vertical-align: middle;
}

:deep(.publish-management-table .publish-management-row--pending > td) {
  background: #fffbeb;
}

.publish-cell-stack {
  display: flex;
  min-width: 0;
  max-width: 100%;
  flex-direction: column;
  gap: 2px;
}

.publish-cell-title {
  display: block;
  overflow: hidden;
  color: #1f2937;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.publish-cell-title--compact {
  font-size: 13px;
}

.publish-cell-sub {
  display: block;
  overflow: hidden;
  margin-top: 3px;
  color: #8c8c8c;
  font-size: 12px;
  line-height: 1.5;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.publish-cell-sub--strong {
  color: #475569;
  font-weight: 500;
}

.publish-brand-line {
  display: inline-flex;
  min-width: 0;
  max-width: 100%;
  align-items: center;
  gap: 6px;
  margin-top: 3px;
  color: #64748b;
  font-size: 12px;
  line-height: 1.5;
}

.publish-brand-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.publish-brand-tag {
  flex: 0 0 auto;
  margin-inline-end: 0;
  font-size: 11px;
}

.publish-account-cell {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 10px;
}

.platform-avatar {
  display: inline-flex;
  overflow: hidden;
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  border: 1px solid #e6edf5;
  border-radius: 8px;
  background: #f7f9fc;
  font-size: 12px;
  font-weight: 800;
}

.platform-avatar img {
  width: 20px;
  height: 20px;
  object-fit: contain;
}

.publish-meta-cell {
  width: 100%;
}

.publish-meta-footer {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  color: #94a3b8;
  font-size: 11.5px;
  line-height: 1.6;
}

.attempt-chip {
  display: inline-flex;
  height: 18px;
  align-items: center;
  padding: 0 6px;
  border-radius: 4px;
  background: #f1f5f9;
  color: #475569;
  font-size: 11px;
  font-weight: 600;
}

.meta-divider {
  color: #cbd5e1;
}

.publish-error-row {
  display: block;
  width: 100%;
  min-width: 0;
}

.publish-error-text {
  display: block;
  overflow: hidden;
  max-width: 100%;
  color: #dc2626;
  font-size: 12.5px;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.publish-actions {
  display: flex;
  justify-content: flex-end;
  gap: 4px;
}

.publish-action-btn {
  display: inline-flex;
  width: 30px;
  height: 30px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: 7px;
  color: #64748b;
}

.publish-action-btn:hover:not(:disabled) {
  background: #eff6ff;
  color: #1677ff;
}

.publish-action-btn--danger:hover:not(:disabled) {
  background: #fff1f0;
  color: #cf1322;
}

.publish-action-tooltip-wrap {
  display: inline-flex;
}

.publish-action-placeholder {
  display: inline-flex;
  width: 30px;
  height: 30px;
  align-items: center;
  justify-content: center;
  color: #cbd5e1;
}

.publish-management-view__pagination {
  display: flex;
  justify-content: flex-end;
  padding: 16px 24px 24px;
}

:global(.publish-error-popover .ant-popover-inner) {
  max-width: min(720px, 82vw);
  border: 1px solid #fecaca;
  border-radius: 8px;
  box-shadow: 0 18px 38px rgba(15, 23, 42, 0.16);
}

:global(.publish-error-popover .ant-popover-inner-content) {
  padding: 12px;
}

:global(.publish-error-panel) {
  display: flex;
  min-width: min(520px, 76vw);
  max-width: min(720px, 82vw);
  flex-direction: column;
  gap: 10px;
}

:global(.publish-error-panel__title) {
  color: #dc2626;
  font-size: 13px;
  font-weight: 700;
}

:global(.publish-error-panel pre) {
  max-height: 360px;
  margin: 0;
  overflow: auto;
  padding: 10px;
  border: 1px solid #fee2e2;
  border-radius: 6px;
  background: #fff7f7;
  color: #991b1b;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 12px;
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-word;
}

:global(.publish-error-panel__copy) {
  display: inline-flex;
  align-self: flex-end;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 28px;
  padding: 0 10px;
  border: 1px solid #fecaca;
  border-radius: 6px;
  background: #fff;
  color: #dc2626;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
}

@media (max-width: 900px) {
  .publish-management-view__header,
  .publish-management-view__toolbar {
    flex-direction: column;
    align-items: stretch;
  }

  .publish-management-view__summary {
    grid-template-columns: 1fr;
  }

  .summary-chip {
    border-right: none;
    border-bottom: 1px solid #eef2f7;
  }

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

  .publish-management-view__filters {
    flex-direction: column;
    align-items: stretch;
  }

  .publish-management-view__search {
    width: 100%;
  }
}
</style>
