<template>
  <div class="announcement-draft-page art-full-height">
    <ElCard class="art-table-card" shadow="never">
      <!-- 1. 筛选区域 -->
      <ElForm class="flex flex-wrap items-center gap-4" :inline="true">
        <ElFormItem :label="$t('announcementDrafts.filter.type')">
          <ElSelect
            v-model="filters.type"
            clearable
            class="w-52"
            :placeholder="$t('announcementDrafts.filter.typePlaceholder')"
          >
            <ElOption
              v-for="option in announcementTypeOptions"
              :key="option.value ?? 'all'"
              :label="option.label"
              :value="option.value"
            />
          </ElSelect>
        </ElFormItem>
        <ElFormItem :label="$t('announcementDrafts.filter.date')">
          <ElDatePicker
            v-model="filters.dateRange"
            type="daterange"
            unlink-panels
            range-separator="-"
            class="w-80"
            :start-placeholder="$t('announcementDrafts.filter.dateStart')"
            :end-placeholder="$t('announcementDrafts.filter.dateEnd')"
          />
        </ElFormItem>
        <ElFormItem>
          <ElSpace>
            <ElButton type="primary" :loading="listLoading" @click="handleSearch">
              {{ $t('table.searchBar.search') }}
            </ElButton>
            <ElButton @click="handleReset">{{ $t('table.searchBar.reset') }}</ElButton>
          </ElSpace>
        </ElFormItem>
      </ElForm>

      <!-- 2. 错误提示 -->
      <ElAlert
        v-if="errorMessage"
        class="mb-4"
        type="error"
        show-icon
        :closable="false"
        :title="$t('announcementDrafts.message.loadFailed')"
        :description="errorMessage"
      />

      <!-- 3. 草稿表格 -->
      <ElTable
        v-loading="listLoading"
        :data="pagedDrafts"
        row-key="id"
        class="w-full"
        :empty-text="$t('announcementDrafts.table.empty')"
      >
        <ElTableColumn :label="$t('announcementDrafts.table.title')" min-width="260">
          <template #default="{ row }">
            <div class="flex items-center gap-2">
              <span class="max-w-[320px] truncate">{{ row.title }}</span>
              <ElTag size="small" :type="row.source === 'local' ? 'info' : 'success'">
                {{
                  row.source === 'local'
                    ? $t('announcementDrafts.source.local')
                    : $t('announcementDrafts.source.server')
                }}
              </ElTag>
            </div>
          </template>
        </ElTableColumn>
        <ElTableColumn :label="$t('announcementDrafts.table.type')" min-width="160">
          <template #default="{ row }">
            {{ formatAnnouncementType(row.announcementType) }}
          </template>
        </ElTableColumn>
        <ElTableColumn :label="$t('announcementDrafts.table.lastSaved')" min-width="180">
          <template #default="{ row }">
            {{ formatDateTime(row.lastSaved) }}
          </template>
        </ElTableColumn>
        <ElTableColumn :label="$t('announcementDrafts.table.author')" min-width="160">
          <template #default="{ row }">
            {{ row.author }}
          </template>
        </ElTableColumn>
        <ElTableColumn :label="$t('table.column.action')" width="220" fixed="right">
          <template #default="{ row }">
            <ElSpace>
              <ElButton
                type="primary"
                link
                :loading="isRowLoading(row.id)"
                @click="handleContinueEdit(row)"
              >
                {{ $t('announcementDrafts.action.continueEdit') }}
              </ElButton>
              <ElButton
                type="danger"
                link
                :loading="isRowLoading(row.id)"
                @click="handleDelete(row)"
              >
                {{ $t('common.delete') }}
              </ElButton>
              <ElButton
                type="success"
                link
                :loading="isRowLoading(row.id)"
                @click="handlePublish(row)"
              >
                {{ $t('announcementDrafts.action.publish') }}
              </ElButton>
            </ElSpace>
          </template>
        </ElTableColumn>
      </ElTable>

      <!-- 4. 分页 -->
      <div class="mt-4 flex flex-wrap items-center justify-between gap-2 text-sm text-gray-500">
        <div>{{ $t('announcementDrafts.pagination.total', { count: filteredDrafts.length }) }}</div>
        <ElPagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.pageSize"
          :page-sizes="pageSizeOptions"
          :total="filteredDrafts.length"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handlePageChange"
        />
      </div>
    </ElCard>
  </div>
</template>

<script setup lang="ts">
  import { computed, onMounted, ref, watch } from 'vue'
  import { useI18n } from 'vue-i18n'
  import { useRouter } from 'vue-router'
  import { ElMessage, ElMessageBox } from 'element-plus'
  import { StorageKeyManager } from '@/utils/storage/storage-key-manager'
  import { StorageConfig } from '@/utils/storage/storage-config'
  import { useAnnouncementStore } from '@/store/modules/announcement'
  import { useUserStore } from '@/store/modules/user'
  import {
    TenantAnnouncementType,
    type AnnouncementDraft,
    type AnnouncementQueryParams,
    type IsoDateTimeString,
    type TenantAnnouncementDto
  } from '@/types/announcement'

  defineOptions({ name: 'AnnouncementDrafts' })

  const { t } = useI18n()
  const router = useRouter()
  const announcementStore = useAnnouncementStore()
  const userStore = useUserStore()

  // 1. 常量配置
  const DRAFT_STORE_ID = 'announcement-draft'
  const DRAFT_EXPIRE_DAYS = 7
  const DRAFT_EXPIRE_MS = DRAFT_EXPIRE_DAYS * 24 * 60 * 60 * 1000
  const SERVER_PAGE_SIZE = 100
  const EDITOR_ROUTE_NAME = 'AnnouncementEditor'
  const EDITOR_ROUTE_PATH = '/announcement/editor'

  const storageKeyManager = new StorageKeyManager()
  const pageSizeOptions = [10, 20, 50]

  // 2. 列表状态
  const listLoading = ref(false)
  const errorMessage = ref('')
  const localDrafts = ref<AnnouncementDraft[]>([])
  const serverDrafts = ref<TenantAnnouncementDto[]>([])
  const actionLoadingIds = ref<string[]>([])

  const filters = ref({
    type: undefined as TenantAnnouncementType | undefined,
    dateRange: [] as [Date, Date] | []
  })

  const pagination = ref({
    page: 1,
    pageSize: 20
  })

  interface DraftRow {
    id: string
    source: 'local' | 'server'
    title: string
    announcementType: TenantAnnouncementType | null
    lastSaved: IsoDateTimeString | null
    author: string
    rowVersion?: string | null
    draftId?: string
    announcementId?: string
  }

  // 3. 选项配置
  const announcementTypeOptions = computed(() => [
    { value: TenantAnnouncementType.System, label: t('announcementDrafts.type.system') },
    { value: TenantAnnouncementType.Billing, label: t('announcementDrafts.type.billing') },
    { value: TenantAnnouncementType.Operation, label: t('announcementDrafts.type.operation') },
    {
      value: TenantAnnouncementType.SYSTEM_PLATFORM_UPDATE,
      label: t('announcementDrafts.type.systemPlatformUpdate')
    },
    {
      value: TenantAnnouncementType.SYSTEM_SECURITY_NOTICE,
      label: t('announcementDrafts.type.systemSecurityNotice')
    },
    {
      value: TenantAnnouncementType.SYSTEM_COMPLIANCE,
      label: t('announcementDrafts.type.systemCompliance')
    },
    {
      value: TenantAnnouncementType.TENANT_INTERNAL,
      label: t('announcementDrafts.type.tenantInternal')
    },
    {
      value: TenantAnnouncementType.TENANT_FINANCE,
      label: t('announcementDrafts.type.tenantFinance')
    },
    {
      value: TenantAnnouncementType.TENANT_OPERATION,
      label: t('announcementDrafts.type.tenantOperation')
    }
  ])

  const currentUserName = computed(() => {
    return (
      userStore.info?.displayName ||
      userStore.info?.account ||
      t('announcementDrafts.field.unknownAuthor')
    )
  })

  // 4. 组合后的草稿列表
  const mergedDrafts = computed<DraftRow[]>(() => {
    // 1. 合成本地草稿行
    const localRows = localDrafts.value.map((draft) => ({
      id: draft.draftId,
      source: 'local' as const,
      title: draft.title?.trim() || t('announcementDrafts.field.untitled'),
      announcementType: draft.announcementType ?? null,
      lastSaved: draft.lastSaved,
      author: currentUserName.value,
      draftId: draft.draftId
    }))

    // 2. 合成服务端草稿行
    const serverRows = serverDrafts.value.map((draft) => ({
      id: String(draft.id),
      source: 'server' as const,
      title: draft.title?.trim() || t('announcementDrafts.field.untitled'),
      announcementType: draft.announcementType ?? null,
      lastSaved: resolveServerLastSaved(draft),
      author: draft.publisherUserId ? String(draft.publisherUserId) : currentUserName.value,
      rowVersion: draft.rowVersion ?? null,
      announcementId: String(draft.id)
    }))

    // 3. 合并并按保存时间倒序
    return [...localRows, ...serverRows].sort(
      (left, right) => resolveTimestamp(right.lastSaved) - resolveTimestamp(left.lastSaved)
    )
  })

  const filteredDrafts = computed(() => {
    // 1. 准备筛选条件
    const typeFilter = filters.value.type
    const range = filters.value.dateRange
    const hasRange = Array.isArray(range) && range.length === 2

    // 2. 过滤草稿列表
    return mergedDrafts.value.filter((item) => {
      // 1. 类型筛选
      if (typeFilter !== undefined && item.announcementType !== typeFilter) {
        return false
      }

      // 2. 时间筛选
      if (hasRange) {
        const [start, end] = range
        const timestamp = resolveTimestamp(item.lastSaved)
        if (!Number.isFinite(timestamp)) {
          return false
        }
        if (start && timestamp < start.getTime()) {
          return false
        }
        if (end && timestamp > end.getTime()) {
          return false
        }
      }

      return true
    })
  })

  const pagedDrafts = computed(() => {
    // 1. 计算分页区间
    const start = (pagination.value.page - 1) * pagination.value.pageSize
    const end = start + pagination.value.pageSize

    // 2. 返回分页数据
    return filteredDrafts.value.slice(start, end)
  })

  // 5. 草稿工具函数
  const escapeRegExp = (value: string) => {
    return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  }

  const getDraftKeys = () => {
    // 1. 构建当前版本前缀
    const currentPrefix = storageKeyManager.getStorageKey(DRAFT_STORE_ID)
    const currentPattern = new RegExp(`^${escapeRegExp(currentPrefix)}:`)

    // 2. 构建历史版本前缀（用于清理旧版本草稿）
    const legacyPattern = new RegExp(`^${StorageConfig.STORAGE_PREFIX}[^-]+-${DRAFT_STORE_ID}:`)

    // 3. 返回匹配的存储键
    return Object.keys(localStorage).filter(
      (key) => currentPattern.test(key) || legacyPattern.test(key)
    )
  }

  const isAnnouncementDraft = (value: unknown): value is AnnouncementDraft => {
    // 1. 基础类型校验
    if (!value || typeof value !== 'object') {
      return false
    }

    // 2. 关键字段校验
    const record = value as Record<string, unknown>
    return typeof record.draftId === 'string' && typeof record.lastSaved === 'string'
  }

  const resolveTimestamp = (value?: string | null) => {
    // 1. 空值直接返回 0
    if (!value) {
      return 0
    }

    // 2. 解析时间戳
    const timestamp = Date.parse(value)
    return Number.isFinite(timestamp) ? timestamp : 0
  }

  const resolveServerLastSaved = (draft: TenantAnnouncementDto): IsoDateTimeString | null => {
    // 1. 兼容后端可能返回的更新时间字段
    const candidateFields = ['updatedAt', 'lastSaved', 'modifiedAt', 'createdAt'] as const
    const record = draft as unknown as Record<string, unknown>
    for (const field of candidateFields) {
      const value = record[field]
      if (typeof value === 'string' && value) {
        return value
      }
    }

    // 2. 使用现有字段兜底（后端 DTO 暂无更新时间字段）
    return draft.scheduledPublishAt || draft.publishedAt || draft.effectiveFrom || null
  }

  const formatDateTime = (value?: string | null) => {
    // 1. 处理空值
    if (!value) {
      return t('announcementDrafts.field.unknown')
    }

    // 2. 处理非法日期
    const timestamp = Date.parse(value)
    if (!Number.isFinite(timestamp)) {
      return t('announcementDrafts.field.unknown')
    }

    return new Date(timestamp).toLocaleString()
  }

  const formatAnnouncementType = (type: TenantAnnouncementType | null) => {
    // 1. 查找匹配选项
    const match = announcementTypeOptions.value.find((option) => option.value === type)

    // 2. 返回类型名称
    return match?.label || t('announcementDrafts.type.unknown')
  }

  const setRowLoading = (id: string, loading: boolean) => {
    // 1. 追加加载标记
    if (loading) {
      if (!actionLoadingIds.value.includes(id)) {
        actionLoadingIds.value.push(id)
      }
      return
    }

    // 2. 移除加载标记
    actionLoadingIds.value = actionLoadingIds.value.filter((item) => item !== id)
  }

  const isRowLoading = (id: string) => {
    return actionLoadingIds.value.includes(id)
  }

  // 6. 草稿加载与清理
  const loadLocalDrafts = () => {
    // 1. 获取草稿存储键
    const draftKeys = getDraftKeys()
    const currentPrefix = storageKeyManager.getStorageKey(DRAFT_STORE_ID)

    // 2. 遍历草稿并清理异常数据
    const drafts: AnnouncementDraft[] = []
    const now = Date.now()

    draftKeys.forEach((key) => {
      const raw = localStorage.getItem(key)
      if (!raw) {
        localStorage.removeItem(key)
        return
      }

      let parsed: unknown
      try {
        parsed = JSON.parse(raw)
      } catch {
        localStorage.removeItem(key)
        return
      }

      if (!isAnnouncementDraft(parsed)) {
        localStorage.removeItem(key)
        return
      }

      const lastSavedAt = Date.parse(parsed.lastSaved)
      if (!Number.isFinite(lastSavedAt)) {
        localStorage.removeItem(key)
        return
      }

      if (now - lastSavedAt > DRAFT_EXPIRE_MS) {
        localStorage.removeItem(key)
        return
      }

      const currentKey = `${currentPrefix}:${parsed.draftId}`
      if (key !== currentKey) {
        localStorage.setItem(currentKey, JSON.stringify(parsed))
        localStorage.removeItem(key)
      }

      drafts.push(parsed)
    })

    // 3. 按时间排序
    drafts.sort((left, right) => Date.parse(right.lastSaved) - Date.parse(left.lastSaved))

    // 4. 更新本地草稿列表
    localDrafts.value = drafts
  }

  const buildQueryParams = (): AnnouncementQueryParams => {
    // 1. 解析日期范围
    const range = filters.value.dateRange
    const hasRange = Array.isArray(range) && range.length === 2
    const dateFrom = hasRange && range[0] ? range[0].toISOString() : undefined
    const dateTo = hasRange && range[1] ? range[1].toISOString() : undefined

    // 2. 返回查询参数
    return {
      page: 1,
      pageSize: SERVER_PAGE_SIZE,
      status: 'Draft',
      dateFrom,
      dateTo
    }
  }

  const loadServerDrafts = async () => {
    // 1. 初始化分页参数
    const baseParams = buildQueryParams()
    let currentPage = 1
    let totalPages = 1
    const drafts: TenantAnnouncementDto[] = []

    // 2. 循环拉取服务端草稿
    while (currentPage <= totalPages) {
      const params: AnnouncementQueryParams = {
        ...baseParams,
        page: currentPage
      }

      const result = await announcementStore.fetchAnnouncements(params)
      if (!result) {
        errorMessage.value = t('announcementDrafts.message.loadFailed')
        break
      }

      drafts.push(...result.items)
      totalPages = Math.max(result.totalPages, 1)
      currentPage += 1
    }

    // 3. 更新服务端草稿列表
    serverDrafts.value = drafts
  }

  const refreshDrafts = async () => {
    // 1. 初始化状态
    listLoading.value = true
    errorMessage.value = ''

    try {
      // 2. 清理并加载本地草稿
      loadLocalDrafts()

      // 3. 加载服务端草稿
      await loadServerDrafts()
    } catch (error) {
      errorMessage.value =
        error instanceof Error ? error.message : t('announcementDrafts.message.loadFailed')
    } finally {
      listLoading.value = false
    }
  }

  // 7. 操作处理
  const navigateToEditor = async (query: Record<string, string>) => {
    // 1. 优先使用路由名称导航
    const resolvedByName = router.resolve({ name: EDITOR_ROUTE_NAME, query })
    if (resolvedByName.matched.length > 0) {
      await router.push({ name: EDITOR_ROUTE_NAME, query })
      return
    }

    // 2. 兜底使用路由路径导航
    const resolvedByPath = router.resolve({ path: EDITOR_ROUTE_PATH, query })
    if (resolvedByPath.matched.length > 0) {
      await router.push({ path: EDITOR_ROUTE_PATH, query })
      return
    }

    // 3. 未找到路由时给出提示
    ElMessage.error(t('announcementDrafts.message.routeNotFound'))
  }

  const handleContinueEdit = async (row: DraftRow) => {
    // 1. 本地草稿直接加载
    if (row.source === 'local' && row.draftId) {
      const draft = announcementStore.loadDraft(row.draftId)
      if (!draft) {
        ElMessage.warning(t('announcementDrafts.message.draftNotFound'))
        return
      }

      await navigateToEditor({ draftId: row.draftId, source: row.source })
      return
    }

    // 2. 服务端草稿拉取详情
    if (row.source === 'server' && row.announcementId) {
      setRowLoading(row.id, true)

      try {
        const detail = await announcementStore.fetchAnnouncementDetail(row.announcementId)
        if (!detail) {
          ElMessage.error(t('announcementDrafts.message.loadFailed'))
          return
        }

        await navigateToEditor({ announcementId: row.announcementId, source: row.source })
      } finally {
        setRowLoading(row.id, false)
      }
    }
  }

  const handleDelete = async (row: DraftRow) => {
    // 1. 弹窗确认
    try {
      await ElMessageBox.confirm(
        t('announcementDrafts.message.deleteConfirm'),
        t('announcementDrafts.message.deleteTitle'),
        {
          confirmButtonText: t('common.confirm'),
          cancelButtonText: t('common.cancel'),
          type: 'warning'
        }
      )
    } catch {
      return
    }

    // 2. 执行删除逻辑
    if (row.source === 'local' && row.draftId) {
      announcementStore.clearDraft(row.draftId)
      loadLocalDrafts()
      ElMessage.success(t('announcementDrafts.message.deleteSuccess'))
      return
    }

    if (row.source === 'server' && row.announcementId) {
      setRowLoading(row.id, true)

      try {
        const success = await announcementStore.deleteAnnouncement(row.announcementId)
        if (success) {
          serverDrafts.value = serverDrafts.value.filter(
            (item) => String(item.id) !== row.announcementId
          )
          ElMessage.success(t('announcementDrafts.message.deleteSuccess'))
        }
      } finally {
        setRowLoading(row.id, false)
      }
    }
  }

  const handlePublish = async (row: DraftRow) => {
    // 1. 本地草稿提示进入编辑页发布
    if (row.source === 'local' && row.draftId) {
      ElMessage.info(t('announcementDrafts.message.localPublishHint'))
      await navigateToEditor({ draftId: row.draftId, source: row.source, autoPublish: '1' })
      return
    }

    // 2. 校验版本号
    if (!row.rowVersion || !row.announcementId) {
      ElMessage.error(t('announcementDrafts.message.missingRowVersion'))
      return
    }

    // 3. 弹窗确认发布
    try {
      await ElMessageBox.confirm(
        t('announcementDrafts.message.publishConfirm'),
        t('announcementDrafts.message.publishTitle'),
        {
          confirmButtonText: t('common.confirm'),
          cancelButtonText: t('common.cancel'),
          type: 'success'
        }
      )
    } catch {
      return
    }

    // 4. 调用发布接口
    setRowLoading(row.id, true)

    try {
      const result = await announcementStore.publishAnnouncement(row.announcementId, row.rowVersion)
      if (result) {
        serverDrafts.value = serverDrafts.value.filter(
          (item) => String(item.id) !== row.announcementId
        )
        ElMessage.success(t('announcementDrafts.message.publishSuccess'))
      }
    } finally {
      setRowLoading(row.id, false)
    }
  }

  const handleSearch = async () => {
    // 1. 重置分页
    pagination.value.page = 1

    // 2. 重新加载草稿
    await refreshDrafts()
  }

  const handleReset = async () => {
    // 1. 重置筛选条件
    filters.value.type = undefined
    filters.value.dateRange = []

    // 2. 重置分页
    pagination.value.page = 1

    // 3. 重新加载草稿
    await refreshDrafts()
  }

  const handlePageChange = (page: number) => {
    // 1. 更新当前页
    pagination.value.page = page
  }

  const handleSizeChange = (size: number) => {
    // 1. 更新每页条数
    pagination.value.pageSize = size

    // 2. 回到第一页
    pagination.value.page = 1
  }

  // 8. 监听筛选变化，保证分页在有效范围内
  watch(filteredDrafts, (list) => {
    // 1. 计算最大页数
    const maxPage = Math.max(1, Math.ceil(list.length / pagination.value.pageSize))

    // 2. 自动修正页码
    if (pagination.value.page > maxPage) {
      pagination.value.page = 1
    }
  })

  // 9. 生命周期
  onMounted(() => {
    refreshDrafts()
  })
</script>
