<!-- 应用端公告详情页面 -->
<template>
  <div class="app-announcement-detail-page space-y-4">
    <ElAlert v-if="errorMessage" type="error" :closable="false" :title="errorMessage" show-icon />

    <div v-loading="loading" class="space-y-4">
      <ElCard shadow="never" class="border-0">
        <div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
          <div class="space-y-2">
            <div class="flex flex-wrap items-center gap-2">
              <ElBadge
                :is-dot="Boolean(currentAnnouncement && !currentAnnouncement.isRead)"
                :hidden="!currentAnnouncement || currentAnnouncement.isRead"
                type="danger"
              />
              <h2 class="text-lg font-semibold text-slate-900">
                {{ currentAnnouncement?.title || $t('appAnnouncement.detail.title') }}
              </h2>
              <ElTag v-if="currentAnnouncement" size="small" type="info">
                {{ resolveTypeLabel(currentAnnouncement.announcementType) }}
              </ElTag>
            </div>
            <div class="flex flex-wrap items-center gap-4 text-sm text-slate-500">
              <span>{{ $t('appAnnouncement.detail.publisher') }}{{ publisherDisplay }}</span>
              <span>
                {{ $t('appAnnouncement.detail.publishedAt')
                }}{{ formatDateTime(currentAnnouncement?.publishedAt) }}
              </span>
              <span>
                {{ $t('appAnnouncement.detail.effective')
                }}{{
                  formatEffectiveRange(
                    currentAnnouncement?.effectiveFrom,
                    currentAnnouncement?.effectiveTo
                  )
                }}
              </span>
            </div>
          </div>

          <ElButton @click="handleBack">{{ $t('appAnnouncement.detail.back') }}</ElButton>
        </div>
      </ElCard>

      <ElCard v-if="currentAnnouncement" shadow="never" class="border-0">
        <div class="mb-3 text-sm font-medium text-slate-700">
          {{ $t('appAnnouncement.detail.content') }}
        </div>
        <div
          class="whitespace-normal text-sm leading-relaxed text-slate-700"
          v-html="sanitizedContent"
        />
      </ElCard>

      <ElEmpty v-else :description="$t('appAnnouncement.message.detailNotFound')" class="py-16" />
    </div>
  </div>
</template>

<script setup lang="ts">
  import { computed, ref, watch } from 'vue'
  import { storeToRefs } from 'pinia'
  import { useRoute, useRouter } from 'vue-router'
  import { useI18n } from 'vue-i18n'
  import DOMPurify from 'dompurify'
  import { useAnnouncementStore } from '@/store/modules/announcement'
  import type { AnnouncementQueryParams, TenantAnnouncementDto } from '@/types/announcement'
  import { TenantAnnouncementType } from '@/types/announcement'

  defineOptions({ name: 'AppAnnouncementDetail' })

  // 1. 路由与状态管理
  const route = useRoute()
  const router = useRouter()
  const announcementStore = useAnnouncementStore()
  const { currentAnnouncement, loading } = storeToRefs(announcementStore)

  // 2. 国际化
  const { t } = useI18n()

  // 3. 页面状态
  const errorMessage = ref('')
  const hasMarkedRead = ref(false)

  // 4. 解析公告ID
  const announcementId = computed(() => {
    const queryId = route.query.id
    const paramId = route.params.id
    const normalizedQuery = Array.isArray(queryId) ? queryId[0] : queryId
    const normalizedParam = Array.isArray(paramId) ? paramId[0] : paramId
    return normalizedQuery || normalizedParam || ''
  })

  // 5. 类型映射
  const typeLabelMap = computed<Record<number, string>>(() => ({
    [TenantAnnouncementType.System]: t('appAnnouncement.type.system'),
    [TenantAnnouncementType.Billing]: t('appAnnouncement.type.billing'),
    [TenantAnnouncementType.Operation]: t('appAnnouncement.type.operation'),
    [TenantAnnouncementType.SYSTEM_PLATFORM_UPDATE]: t('appAnnouncement.type.platformUpdate'),
    [TenantAnnouncementType.SYSTEM_SECURITY_NOTICE]: t('appAnnouncement.type.security'),
    [TenantAnnouncementType.SYSTEM_COMPLIANCE]: t('appAnnouncement.type.compliance'),
    [TenantAnnouncementType.TENANT_INTERNAL]: t('appAnnouncement.type.tenantInternal'),
    [TenantAnnouncementType.TENANT_FINANCE]: t('appAnnouncement.type.tenantFinance'),
    [TenantAnnouncementType.TENANT_OPERATION]: t('appAnnouncement.type.tenantOperation')
  }))

  // 6. 富文本内容清洗
  const sanitizedContent = computed(() => {
    const raw = currentAnnouncement.value?.content || ''
    return DOMPurify.sanitize(raw)
  })

  // 7. 发布者展示
  const publisherDisplay = computed(() => {
    const announcement = currentAnnouncement.value
    if (!announcement) {
      return t('appAnnouncement.common.notAvailable')
    }

    const scopeText = resolvePublisherScope(announcement.publisherScope)
    if (announcement.publisherUserId) {
      return `${announcement.publisherUserId} (${scopeText})`
    }

    return scopeText
  })

  /**
   * 格式化日期时间
   */
  const formatDateTime = (value?: string | null) => {
    // 1. 空值处理
    if (!value) {
      return t('appAnnouncement.common.notAvailable')
    }

    // 2. 解析时间
    const date = new Date(value)
    if (Number.isNaN(date.getTime())) {
      return t('appAnnouncement.common.notAvailable')
    }

    // 3. 返回本地化字符串
    return date.toLocaleString()
  }

  /**
   * 格式化有效期范围
   */
  const formatEffectiveRange = (start?: string, end?: string | null) => {
    // 1. 格式化起止时间
    const startText = formatDateTime(start)
    const endText = end ? formatDateTime(end) : t('appAnnouncement.common.notAvailable')

    // 2. 输出范围
    return t('appAnnouncement.common.dateRange', { start: startText, end: endText })
  }

  /**
   * 获取公告类型名称
   */
  const resolveTypeLabel = (type: TenantAnnouncementType) => {
    // 1. 返回类型文本
    return typeLabelMap.value[type] || t('appAnnouncement.common.notAvailable')
  }

  /**
   * 获取发布范围文本
   */
  const resolvePublisherScope = (scope?: string | null) => {
    // 1. 平台公告
    if (scope === 'Platform') {
      return t('appAnnouncement.publisher.platform')
    }

    // 2. 租户公告
    if (scope === 'Tenant') {
      return t('appAnnouncement.publisher.tenant')
    }

    // 3. 未知范围
    return t('appAnnouncement.publisher.unknown')
  }

  /**
   * 自动标记已读
   */
  const markAsReadIfNeeded = async (announcement: TenantAnnouncementDto) => {
    // 1. 已读状态直接跳过
    if (announcement.isRead || hasMarkedRead.value) {
      return
    }

    // 2. 调用已读接口
    await announcementStore.markAsRead(announcement.id, { scope: 'app' })

    // 3. 刷新未读数量并记录状态
    await announcementStore.fetchUnreadCount()
    hasMarkedRead.value = true
  }

  /**
   * 加载公告详情
   */
  const loadDetail = async () => {
    // 1. 初始化错误状态
    errorMessage.value = ''

    // 2. 校验公告ID
    if (!announcementId.value) {
      errorMessage.value = t('appAnnouncement.message.missingId')
      return
    }

    // 3. 拉取列表缓存（防止直接进入详情页）
    if (!announcementStore.announcements.length) {
      const params: AnnouncementQueryParams & { isActive?: boolean } = {
        page: 1,
        pageSize: 20,
        status: 'Published',
        onlyEffective: true,
        isActive: true
      }
      await announcementStore.fetchAnnouncements(params, { scope: 'app' })
    }

    // 4. 读取公告详情
    const result = await announcementStore.fetchAnnouncementDetail(announcementId.value, {
      scope: 'app'
    })

    if (!result) {
      errorMessage.value = t('appAnnouncement.message.detailNotFound')
      return
    }

    // 5. 自动标记已读
    await markAsReadIfNeeded(result)
  }

  /**
   * 返回公告列表
   */
  const handleBack = () => {
    // 1. 返回列表页
    router.push({ path: '/app/announcements' })
  }

  watch(
    announcementId,
    () => {
      // 1. 重置已读标记状态
      hasMarkedRead.value = false

      // 2. 重新加载详情
      loadDetail()
    },
    { immediate: true }
  )
</script>
