<template>
  <div class="art-page-view space-y-4">
    <ElCard shadow="never" v-loading="pageLoading">
      <div class="flex flex-wrap items-start justify-between gap-4">
        <div class="space-y-2">
          <div class="text-lg font-semibold">
            {{ announcement?.title || t('announcement.common.empty') }}
          </div>
          <div class="flex flex-wrap items-center gap-2">
            <ElTag :type="announcement ? getStatusTagType(announcement.status) : 'info'">
              {{
                announcement
                  ? getStatusLabel(announcement.status)
                  : t('announcement.status.unknown')
              }}
            </ElTag>
            <ElTag type="info">
              {{
                announcement
                  ? getTypeLabel(announcement.announcementType)
                  : t('announcement.type.unknown')
              }}
            </ElTag>
            <ElTag v-if="announcement" type="warning">
              {{ t('announcement.detail.priority') }}: {{ announcement.priority }}
            </ElTag>
          </div>
        </div>
        <div class="flex items-center gap-2">
          <ElButton v-if="isDraft" type="primary" :loading="loading" @click="handleEdit">
            {{ t('announcement.action.edit') }}
          </ElButton>
          <ElButton v-if="isDraft" type="success" :loading="loading" @click="handlePublish">
            {{ t('announcement.action.publish') }}
          </ElButton>
          <ElButton v-if="isPublished" type="warning" :loading="loading" @click="handleRevoke">
            {{ t('announcement.action.revoke') }}
          </ElButton>
          <ElButton @click="handleBack">
            {{ t('announcement.action.back') }}
          </ElButton>
        </div>
      </div>

      <ElDescriptions class="mt-6" :column="2" border>
        <ElDescriptionsItem :label="t('announcement.detail.id')">
          {{ announcement?.id || t('announcement.common.empty') }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('announcement.detail.status')">
          {{
            announcement ? getStatusLabel(announcement.status) : t('announcement.status.unknown')
          }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('announcement.detail.type')">
          {{
            announcement
              ? getTypeLabel(announcement.announcementType)
              : t('announcement.type.unknown')
          }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('announcement.detail.priority')">
          {{ announcement?.priority ?? t('announcement.common.empty') }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('announcement.detail.effectiveFrom')">
          {{ formatDateTime(announcement?.effectiveFrom) }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('announcement.detail.effectiveTo')">
          {{ formatDateTime(announcement?.effectiveTo) }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('announcement.detail.publishedAt')">
          {{ formatDateTime(announcement?.publishedAt) }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('announcement.detail.revokedAt')">
          {{ formatDateTime(announcement?.revokedAt) }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('announcement.detail.targetType')">
          {{
            announcement
              ? getTargetTypeLabel(announcement.targetType)
              : t('announcement.common.empty')
          }}
        </ElDescriptionsItem>
        <ElDescriptionsItem :label="t('announcement.detail.publisherScope')">
          {{ announcement?.publisherScope || t('announcement.common.empty') }}
        </ElDescriptionsItem>
        <ElDescriptionsItem
          v-if="targetParametersDisplay"
          :label="t('announcement.detail.targetParameters')"
          :span="2"
        >
          <div class="text-sm text-gray-600 whitespace-pre-wrap">{{ targetParametersDisplay }}</div>
        </ElDescriptionsItem>
      </ElDescriptions>
    </ElCard>

    <ElCard shadow="never">
      <div class="text-base font-semibold mb-3">{{ t('announcement.detail.content') }}</div>
      <ElAlert v-if="!announcement?.content" type="info" :closable="false">
        {{ t('announcement.detail.contentPlaceholder') }}
      </ElAlert>
      <div v-else class="prose max-w-none">
        <div class="rich-text-content" v-html="sanitizedContent"></div>
      </div>
    </ElCard>

    <ElCard shadow="never">
      <div class="text-base font-semibold">{{ t('announcement.detail.readStats') }}</div>
      <ElEmpty :description="t('announcement.detail.readStatsPlaceholder')" />
    </ElCard>
  </div>
</template>

<script setup lang="ts">
  import { computed, onMounted, ref } from 'vue'
  import { useI18n } from 'vue-i18n'
  import { useRoute, useRouter } from 'vue-router'
  import { storeToRefs } from 'pinia'
  import DOMPurify from 'dompurify'
  import {
    ElAlert,
    ElButton,
    ElCard,
    ElDescriptions,
    ElDescriptionsItem,
    ElEmpty,
    ElMessage,
    ElMessageBox,
    ElTag
  } from 'element-plus'
  import { platformAnnouncementApi } from '@/api/announcement'
  import { useAnnouncementStore } from '@/store/modules/announcement'
  import { normalizeAnnouncementStatus } from '@/utils/announcementStatus'
  import type {
    AnnouncementStatus,
    AnnouncementTargetType,
    TargetRules,
    TenantAnnouncementDto,
    TenantAnnouncementType
  } from '@/types/announcement'
  import { TenantAnnouncementType as TenantAnnouncementTypeEnum } from '@/types/announcement'

  defineOptions({ name: 'PlatformAnnouncementDetail' })

  const { t } = useI18n()
  const route = useRoute()
  const router = useRouter()

  // 1. 初始化 Store 与加载状态
  const announcementStore = useAnnouncementStore()
  const { loading } = storeToRefs(announcementStore)
  const pageLoading = ref(false)

  // 2. 详情数据
  const announcement = ref<TenantAnnouncementDto | null>(null)

  // 3. 计算属性
  const resolveStatus = (status: unknown) => normalizeAnnouncementStatus(status)
  const isDraft = computed(() => resolveStatus(announcement.value?.status) === 'Draft')
  const isPublished = computed(() => resolveStatus(announcement.value?.status) === 'Published')

  const sanitizedContent = computed(() => {
    if (!announcement.value?.content) {
      return ''
    }
    // 1. 使用 DOMPurify 清洗 HTML,防止 XSS 攻击
    return DOMPurify.sanitize(announcement.value.content, {
      ALLOWED_TAGS: [
        'p',
        'br',
        'strong',
        'em',
        'u',
        's',
        'h1',
        'h2',
        'h3',
        'h4',
        'h5',
        'h6',
        'ul',
        'ol',
        'li',
        'a',
        'blockquote',
        'pre',
        'code',
        'span',
        'div'
      ],
      ALLOWED_ATTR: ['href', 'target', 'rel', 'class', 'style']
    })
  })

  const targetParametersDisplay = computed(() => {
    if (!announcement.value?.targetParameters) {
      return ''
    }

    try {
      // 1. 解析 targetParameters JSON 字符串
      const params = JSON.parse(announcement.value.targetParameters) as TargetRules

      // 2. 格式化显示
      const lines: string[] = []
      if (params.departments && params.departments.length > 0) {
        lines.push(`部门: ${params.departments.join(', ')}`)
      }
      if (params.roles && params.roles.length > 0) {
        lines.push(`角色: ${params.roles.join(', ')}`)
      }
      if (params.tags && params.tags.length > 0) {
        lines.push(`标签: ${params.tags.join(', ')}`)
      }

      return lines.length > 0 ? lines.join('\n') : ''
    } catch {
      // 3. 解析失败时返回原始 JSON
      return announcement.value.targetParameters
    }
  })

  // 4. 跳转操作
  const handleBack = () => {
    // 1. 返回上一页
    router.back()
  }

  const handleEdit = () => {
    if (!announcement.value) {
      return
    }
    // 1. 跳转到编辑页
    router.push({
      path: `/platform/announcements/${announcement.value.id}/edit`
    })
  }

  // 5. 确认对话框
  const confirmAction = async (message: string) => {
    try {
      // 1. 弹出二次确认
      await ElMessageBox.confirm(message, t('common.tips'), {
        type: 'warning',
        confirmButtonText: t('common.confirm'),
        cancelButtonText: t('common.cancel')
      })
      return true
    } catch {
      return false
    }
  }

  // 6. 发布操作
  const handlePublish = async () => {
    if (!announcement.value) {
      ElMessage.error(t('announcement.message.loadFailed'))
      return
    }

    if (!announcement.value.rowVersion) {
      ElMessage.error(t('announcement.message.rowVersionMissing'))
      return
    }

    // 1. 二次确认
    const confirmed = await confirmAction(t('announcement.message.publishConfirm'))
    if (!confirmed) {
      return
    }

    try {
      // 2. 调用发布接口
      const result = await announcementStore.publishAnnouncement(
        announcement.value.id,
        announcement.value.rowVersion,
        { scope: 'platform' }
      )

      // 3. 更新本地数据
      if (result) {
        ElMessage.success(t('announcement.message.publishSuccess'))
        announcement.value = result
      }
    } catch (error) {
      console.error('发布失败:', error)
      ElMessage.error(t('announcement.message.publishFailed'))
    }
  }

  // 7. 撤销操作
  const handleRevoke = async () => {
    if (!announcement.value) {
      ElMessage.error(t('announcement.message.loadFailed'))
      return
    }

    if (!announcement.value.rowVersion) {
      ElMessage.error(t('announcement.message.rowVersionMissing'))
      return
    }

    // 1. 二次确认
    const confirmed = await confirmAction(t('announcement.message.revokeConfirm'))
    if (!confirmed) {
      return
    }

    try {
      // 2. 调用撤销接口
      const result = await announcementStore.revokeAnnouncement(
        announcement.value.id,
        announcement.value.rowVersion,
        { scope: 'platform' }
      )

      // 3. 更新本地数据
      if (result) {
        ElMessage.success(t('announcement.message.revokeSuccess'))
        announcement.value = result
      }
    } catch (error) {
      console.error('撤销失败:', error)
      ElMessage.error(t('announcement.message.revokeFailed'))
    }
  }

  // 8. 加载详情
  const loadDetail = async () => {
    // 1. 从路由参数获取公告 ID
    const announcementId = route.params.id ? String(route.params.id) : ''
    if (!announcementId) {
      ElMessage.error(t('announcement.message.missingId'))
      return
    }

    pageLoading.value = true

    try {
      // 2. 直接调用平台公告详情接口
      const detail = await platformAnnouncementApi.detail(announcementId)
      announcement.value = detail
    } catch (error) {
      console.error('加载详情失败:', error)
      ElMessage.error(t('announcement.message.loadFailed'))
    } finally {
      pageLoading.value = false
    }
  }

  // 9. 辅助函数
  const getStatusLabel = (status: AnnouncementStatus) => {
    switch (resolveStatus(status)) {
      case 'Draft':
        return t('announcement.status.draft')
      case 'Published':
        return t('announcement.status.published')
      case 'Revoked':
        return t('announcement.status.revoked')
      default:
        return t('announcement.status.unknown')
    }
  }

  const getStatusTagType = (status: AnnouncementStatus) => {
    switch (resolveStatus(status)) {
      case 'Draft':
        return 'info'
      case 'Published':
        return 'success'
      case 'Revoked':
        return 'danger'
      default:
        return 'info'
    }
  }

  const getTypeLabel = (type: TenantAnnouncementType) => {
    switch (type) {
      case TenantAnnouncementTypeEnum.System:
        return t('announcement.type.system')
      case TenantAnnouncementTypeEnum.Billing:
        return t('announcement.type.billing')
      case TenantAnnouncementTypeEnum.Operation:
        return t('announcement.type.operation')
      case TenantAnnouncementTypeEnum.SYSTEM_PLATFORM_UPDATE:
        return t('announcement.type.platformUpdate')
      case TenantAnnouncementTypeEnum.SYSTEM_SECURITY_NOTICE:
        return t('announcement.type.security')
      case TenantAnnouncementTypeEnum.SYSTEM_COMPLIANCE:
        return t('announcement.type.compliance')
      case TenantAnnouncementTypeEnum.TENANT_INTERNAL:
        return t('announcement.type.tenantInternal')
      case TenantAnnouncementTypeEnum.TENANT_FINANCE:
        return t('announcement.type.tenantFinance')
      case TenantAnnouncementTypeEnum.TENANT_OPERATION:
        return t('announcement.type.tenantOperation')
      default:
        return t('announcement.type.unknown')
    }
  }

  const getTargetTypeLabel = (type: AnnouncementTargetType) => {
    switch (String(type).toLowerCase()) {
      case 'all':
        return t('announcement.targetType.all')
      case 'rules':
        return t('announcement.targetType.rules')
      case 'roles':
        return t('announcement.targetType.roles')
      case 'users':
        return t('announcement.targetType.users')
      case 'manual':
        return t('announcement.targetType.manual')
      default:
        return t('announcement.common.empty')
    }
  }

  const formatDateTime = (value?: string | null) => {
    if (!value) {
      return t('announcement.common.empty')
    }

    // 1. 解析日期
    const date = new Date(value)
    if (Number.isNaN(date.getTime())) {
      return value
    }

    // 2. 格式化为本地时间
    return date.toLocaleString()
  }

  // 10. 生命周期
  onMounted(() => {
    // 1. 加载详情
    void loadDetail()
  })
</script>

<style scoped>
  .art-page-view {
    padding: 16px;
  }

  .rich-text-content {
    padding: 16px;
    line-height: 1.8;
    color: var(--el-text-color-regular);
    background-color: var(--el-bg-color);
    border: 1px solid var(--el-border-color-lighter);
    border-radius: 4px;
  }

  .rich-text-content :deep(p) {
    margin: 0.5em 0;
  }

  .rich-text-content :deep(h1),
  .rich-text-content :deep(h2),
  .rich-text-content :deep(h3),
  .rich-text-content :deep(h4),
  .rich-text-content :deep(h5),
  .rich-text-content :deep(h6) {
    margin: 1em 0 0.5em;
    font-weight: 600;
  }

  .rich-text-content :deep(ul),
  .rich-text-content :deep(ol) {
    padding-left: 2em;
    margin: 0.5em 0;
  }

  .rich-text-content :deep(li) {
    margin: 0.25em 0;
  }

  .rich-text-content :deep(a) {
    color: var(--el-color-primary);
    text-decoration: underline;
  }

  .rich-text-content :deep(blockquote) {
    padding: 8px 16px;
    margin: 0.5em 0;
    background-color: var(--el-fill-color-light);
    border-left: 4px solid var(--el-color-primary);
  }

  .rich-text-content :deep(pre) {
    padding: 12px;
    overflow-x: auto;
    background-color: var(--el-fill-color-darker);
    border-radius: 4px;
  }

  .rich-text-content :deep(code) {
    padding: 2px 6px;
    font-family: 'Courier New', monospace;
    background-color: var(--el-fill-color-light);
    border-radius: 3px;
  }
</style>
