<!-- 应用端公告列表页面 -->
<template>
  <div class="app-announcement-page 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-1">
          <h2 class="text-lg font-semibold text-slate-900">
            {{ $t('appAnnouncement.list.title') }}
          </h2>
          <p class="text-sm text-slate-500">
            {{ $t('appAnnouncement.list.unreadCount', { count: unreadCount }) }}
          </p>
        </div>

        <div class="flex flex-wrap items-center gap-3">
          <ElSelect
            v-model="selectedType"
            class="w-56"
            :placeholder="$t('appAnnouncement.list.typePlaceholder')"
            @change="handleTypeChange"
          >
            <ElOption
              v-for="option in typeOptions"
              :key="String(option.value)"
              :label="option.label"
              :value="option.value"
            />
          </ElSelect>

          <ElButton type="primary" :loading="loading" @click="handleRefresh">
            {{ $t('appAnnouncement.list.refresh') }}
          </ElButton>
        </div>
      </div>
    </ElCard>

    <ElAlert v-if="errorMessage" type="error" :closable="false" :title="errorMessage" show-icon />

    <div v-loading="loading" class="min-h-[240px]">
      <div
        v-if="displayAnnouncements.length"
        class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3"
      >
        <ElCard
          v-for="item in displayAnnouncements"
          :key="item.id"
          shadow="hover"
          class="cursor-pointer transition hover:shadow-md"
          @click="handleViewDetail(item)"
        >
          <div class="flex h-full flex-col gap-3">
            <div class="flex items-start justify-between gap-3">
              <div class="min-w-0 flex-1 space-y-2">
                <div class="flex items-center gap-2">
                  <ElBadge :is-dot="!item.isRead" :hidden="item.isRead" type="danger" />
                  <h3 class="truncate text-base font-semibold text-slate-900">
                    {{ item.title }}
                  </h3>
                </div>
                <div class="flex flex-wrap items-center gap-2 text-xs text-slate-500">
                  <ElTag size="small" type="info">
                    {{ resolveTypeLabel(item.announcementType) }}
                  </ElTag>
                  <span
                    >{{ $t('appAnnouncement.list.publisher') }}{{ resolvePublisher(item) }}</span
                  >
                  <span>
                    {{ $t('appAnnouncement.list.publishedAt')
                    }}{{ formatDateTime(item.publishedAt) }}
                  </span>
                </div>
              </div>

              <ElButton type="primary" link @click.stop="handleViewDetail(item)">
                {{ $t('appAnnouncement.list.viewDetail') }}
              </ElButton>
            </div>

            <div class="text-xs text-slate-500">
              {{ $t('appAnnouncement.list.effective')
              }}{{ formatEffectiveRange(item.effectiveFrom, item.effectiveTo) }}
            </div>
          </div>
        </ElCard>
      </div>

      <ElEmpty v-else :description="$t('appAnnouncement.list.empty')" class="pt-16" />
    </div>

    <div class="flex justify-end">
      <ElPagination
        background
        layout="total, sizes, prev, pager, next, jumper"
        :current-page="pagination.page"
        :page-size="pagination.pageSize"
        :page-sizes="[8, 12, 20, 40]"
        :total="pagination.totalCount"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

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

  defineOptions({ name: 'AppAnnouncementIndex' })

  // 1. 路由与状态管理
  const router = useRouter()
  const announcementStore = useAnnouncementStore()
  const { announcements, pagination, loading, unreadCount } = storeToRefs(announcementStore)

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

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

  // 4. 查询参数（应用端公告）
  type AppAnnouncementQueryParams = AnnouncementQueryParams & {
    announcementType?: TenantAnnouncementType
    isActive?: boolean
  }

  const queryParams = ref<AppAnnouncementQueryParams>({
    page: 1,
    pageSize: 12,
    status: 'Published',
    onlyEffective: true,
    isActive: true
  })

  const selectedType = ref<'all' | TenantAnnouncementType>('all')

  // 5. 选项与映射
  const typeOptions = computed(() => [
    { label: t('appAnnouncement.type.all'), value: 'all' as const },
    { label: t('appAnnouncement.type.system'), value: TenantAnnouncementType.System },
    { label: t('appAnnouncement.type.billing'), value: TenantAnnouncementType.Billing },
    { label: t('appAnnouncement.type.operation'), value: TenantAnnouncementType.Operation },
    {
      label: t('appAnnouncement.type.platformUpdate'),
      value: TenantAnnouncementType.SYSTEM_PLATFORM_UPDATE
    },
    {
      label: t('appAnnouncement.type.security'),
      value: TenantAnnouncementType.SYSTEM_SECURITY_NOTICE
    },
    {
      label: t('appAnnouncement.type.compliance'),
      value: TenantAnnouncementType.SYSTEM_COMPLIANCE
    },
    {
      label: t('appAnnouncement.type.tenantInternal'),
      value: TenantAnnouncementType.TENANT_INTERNAL
    },
    {
      label: t('appAnnouncement.type.tenantFinance'),
      value: TenantAnnouncementType.TENANT_FINANCE
    },
    {
      label: t('appAnnouncement.type.tenantOperation'),
      value: TenantAnnouncementType.TENANT_OPERATION
    }
  ])

  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')
  }))

  const displayAnnouncements = computed(() => announcements.value)

  /**
   * 格式化日期时间
   */
  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 resolvePublisher = (item: TenantAnnouncementDto) => {
    // 1. 优先显示发布人
    if (item.publisherUserId) {
      return item.publisherUserId
    }

    // 2. 根据范围返回默认展示
    if (item.publisherScope === 'Platform') {
      return t('appAnnouncement.publisher.platform')
    }

    if (item.publisherScope === 'Tenant') {
      return t('appAnnouncement.publisher.tenant')
    }

    // 3. 回退未知
    return t('appAnnouncement.publisher.unknown')
  }

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

    // 2. 同步类型筛选
    if (selectedType.value === 'all') {
      queryParams.value.announcementType = undefined
    } else {
      queryParams.value.announcementType = selectedType.value
    }

    // 3. 拉取公告列表
    const result = await announcementStore.fetchAnnouncements(
      queryParams.value as AnnouncementQueryParams,
      { scope: 'app' }
    )

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

    // 4. 刷新未读数量
    await announcementStore.fetchUnreadCount()
  }

  /**
   * 处理类型筛选
   */
  const handleTypeChange = () => {
    // 1. 重置分页并重新加载
    queryParams.value.page = 1
    loadAnnouncements()
  }

  /**
   * 刷新数据
   */
  const handleRefresh = () => {
    // 1. 触发重新加载
    loadAnnouncements()
  }

  /**
   * 切换分页大小
   */
  const handleSizeChange = (size: number) => {
    // 1. 重置分页参数
    queryParams.value.pageSize = size
    queryParams.value.page = 1

    // 2. 重新加载数据
    loadAnnouncements()
  }

  /**
   * 切换当前页
   */
  const handleCurrentChange = (page: number) => {
    // 1. 更新分页参数
    queryParams.value.page = page

    // 2. 重新加载数据
    loadAnnouncements()
  }

  /**
   * 查看公告详情
   */
  const handleViewDetail = (item: TenantAnnouncementDto) => {
    // 1. 同步当前公告到 Store
    announcementStore.currentAnnouncement = item

    // 2. 跳转详情页
    router.push({ path: '/app/announcements/detail', query: { id: item.id } })
  }

  onMounted(() => {
    // 1. 初始化加载
    loadAnnouncements()
  })
</script>
