/**
 * 文件用途：公告模块状态管理
 * 作者：前端架构师（Codex）
 * 日期：2025-12-20
 */

import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { ElMessage } from 'element-plus'
import type {
  AnnouncementDraft,
  AnnouncementFormData,
  AnnouncementQueryParams,
  AnnouncementStatistics,
  AudienceEstimate,
  TargetRules,
  TenantAnnouncementDto
} from '@/types/announcement'
import type { PagedResult } from '@/types/common/response'
import {
  appAnnouncementApi,
  platformAnnouncementApi,
  tenantAnnouncementApi
} from '@/api/announcement'
import { normalizeAnnouncementStatus } from '@/utils/announcementStatus'
import { StorageKeyManager } from '@/utils/storage/storage-key-manager'
import { StorageConfig } from '@/utils/storage/storage-config'
import { useUserStore } from '@/store/modules/user'

/** 公告作用域 */
type AnnouncementScope = 'platform' | 'tenant' | 'app'

/** 公告请求数据（允许传入 targetParameters 以便后端解析） */
type AnnouncementRequestData = AnnouncementFormData & { targetParameters?: string | null }

/** 公告操作可选项 */
interface AnnouncementActionOptions {
  scope?: AnnouncementScope
  tenantId?: string
  silent?: boolean
  skipLoading?: boolean
}

const storageKeyManager = new StorageKeyManager()
const DRAFT_STORE_ID = 'announcement-draft'
const DEFAULT_PAGE = 1
const DEFAULT_PAGE_SIZE = 20
const DEFAULT_DEBOUNCE_MS = 2000
const DEFAULT_AUTO_SAVE_INTERVAL = 30000

/**
 * 公告状态管理 Store
 */
export const useAnnouncementStore = defineStore(
  'announcementStore',
  () => {
    // 1. 公告列表数据
    const announcements = ref<TenantAnnouncementDto[]>([])

    // 2. 当前选中的公告
    const currentAnnouncement = ref<TenantAnnouncementDto | null>(null)

    // 3. 未读公告数
    const unreadCount = ref<number>(0)

    // 4. 统计数据
    const statistics = ref<AnnouncementStatistics | null>(null)

    // 5. 分页信息
    const pagination = ref({
      page: DEFAULT_PAGE,
      pageSize: DEFAULT_PAGE_SIZE,
      totalCount: 0,
      totalPages: 0
    })

    // 6. 加载状态
    const loading = ref<boolean>(false)

    // 7. 草稿数据
    const currentDraft = ref<AnnouncementDraft | null>(null)

    // 8. 草稿自动保存定时器
    let draftAutoSaveTimer: ReturnType<typeof setInterval> | null = null

    // 9. 草稿防抖保存定时器
    let draftDebounceTimer: ReturnType<typeof setTimeout> | null = null

    /**
     * 是否存在未读公告
     */
    const hasUnread = computed(() => unreadCount.value > 0)

    /**
     * 草稿与已发布公告数量（合计）
     */
    const draftPublishedAnnouncements = computed(() => {
      // 1. 优先使用统计数据
      if (statistics.value) {
        return statistics.value.draftCount + statistics.value.publishedCount
      }

      // 2. 回退本地计算
      const draftCount = announcements.value.filter(
        (item) => normalizeAnnouncementStatus(item.status) === 'Draft'
      ).length
      const publishedCount = announcements.value.filter(
        (item) => normalizeAnnouncementStatus(item.status) === 'Published'
      ).length
      return draftCount + publishedCount
    })

    /**
     * 有效期内公告（已发布且在有效期内）
     */
    const effectiveAnnouncements = computed(() => {
      // 1. 获取当前时间
      const now = Date.now()

      // 2. 过滤有效期公告
      return announcements.value.filter((item) => {
        // 1. 解析时间范围
        const startAt = Date.parse(item.effectiveFrom)
        const endAt = item.effectiveTo ? Date.parse(item.effectiveTo) : null
        const startOk = !Number.isNaN(startAt) && startAt <= now
        const endOk = !endAt || now <= endAt

        // 2. 判断有效状态
        return (
          item.isActive &&
          normalizeAnnouncementStatus(item.status) === 'Published' &&
          startOk &&
          endOk
        )
      })
    })

    /**
     * 生成草稿存储键
     */
    const getDraftStorageKey = (draftId: string) => {
      return `${storageKeyManager.getStorageKey(DRAFT_STORE_ID)}:${draftId}`
    }

    /**
     * 生成草稿ID
     */
    const createDraftId = () => {
      return `draft-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
    }

    /**
     * 解析作用域（优先使用显式 scope，其次根据参数判断）
     */
    const resolveScope = (
      options?: AnnouncementActionOptions,
      params?: AnnouncementQueryParams
    ) => {
      // 1. 优先使用显式 scope
      if (options?.scope) {
        return options.scope
      }

      // 2. 根据租户参数推断为租户作用域
      if (params?.tenantId) {
        return 'tenant'
      }

      // 3. 根据当前租户信息判断
      const currentTenantId = resolveTenantId()
      if (currentTenantId && currentTenantId !== '0') {
        return 'tenant'
      }

      // 4. 默认平台作用域
      return 'platform'
    }

    /**
     * 获取租户ID
     */
    const resolveTenantId = (tenantId?: string) => {
      // 1. 优先使用传入 tenantId
      if (tenantId) {
        return tenantId
      }

      // 2. 回退用户信息中的 tenantId
      const userStore = useUserStore()
      if (userStore.info?.tenantId) {
        return userStore.info.tenantId
      }

      // 3. 回退本地存储的 tenantId
      return localStorage.getItem(StorageConfig.TENANT_ID_KEY) || null
    }

    /**
     * 获取错误提示信息
     */
    const resolveErrorMessage = (error: unknown, fallback: string) => {
      // 1. 使用异常信息作为提示
      if (error instanceof Error && error.message) {
        return error.message
      }

      // 2. 回退默认提示
      return fallback
    }

    const handleActionError = (
      error: unknown,
      fallback: string,
      options?: AnnouncementActionOptions
    ) => {
      const message = resolveErrorMessage(error, fallback)
      if (!options?.silent) {
        ElMessage.error(message)
        return null
      }
      throw error instanceof Error ? error : new Error(message)
    }

    /**
     * 构建目标受众参数
     */
    const buildTargetParameters = (data: AnnouncementRequestData): string | null => {
      // 1. 直接使用调用方传入的 targetParameters
      if (typeof data.targetParameters === 'string') {
        return data.targetParameters
      }

      // 2. 规则/角色模式使用规则参数
      if ((data.targetType === 'Rules' || data.targetType === 'Roles') && data.targetRules) {
        return JSON.stringify(data.targetRules)
      }

      // 3. 手选用户模式使用用户ID参数
      if (
        (data.targetType === 'Users' || data.targetType === 'Manual') &&
        data.targetUserIds?.length
      ) {
        return JSON.stringify({ userIds: data.targetUserIds })
      }

      // 4. 默认返回空
      return null
    }

    /**
     * 构建创建公告请求体
     */
    const buildCreatePayload = (data: AnnouncementRequestData) => {
      // 1. 构建创建字段
      return {
        title: data.title,
        content: data.content,
        announcementType: data.announcementType,
        priority: data.priority,
        effectiveFrom: data.effectiveFrom,
        effectiveTo: data.effectiveTo ?? null,
        targetType: data.targetType,
        targetParameters: buildTargetParameters(data)
      }
    }

    /**
     * 构建更新公告请求体
     */
    const buildUpdatePayload = (data: AnnouncementRequestData) => {
      // 1. 构建更新字段
      return {
        title: data.title,
        content: data.content,
        announcementType: data.announcementType,
        priority: data.priority,
        effectiveFrom: data.effectiveFrom,
        effectiveTo: data.effectiveTo ?? null,
        targetType: data.targetType,
        targetParameters: buildTargetParameters(data),
        rowVersion: data.rowVersion
      }
    }

    /**
     * 更新分页状态
     */
    const applyPagedResult = (result: PagedResult<TenantAnnouncementDto>) => {
      // 1. 更新列表数据
      announcements.value = Array.isArray(result.items) ? result.items : []

      // 2. 更新分页信息
      pagination.value = {
        page: result.page,
        pageSize: result.pageSize,
        totalCount: result.totalCount,
        totalPages: result.totalPages
      }
    }

    /**
     * 刷新统计数据
     */
    const refreshStatistics = () => {
      // 1. 统计列表中的状态数量
      const list = announcements.value
      const draftCount = list.filter(
        (item) => normalizeAnnouncementStatus(item.status) === 'Draft'
      ).length
      const publishedCount = list.filter(
        (item) => normalizeAnnouncementStatus(item.status) === 'Published'
      ).length
      const revokedCount = list.filter(
        (item) => normalizeAnnouncementStatus(item.status) === 'Revoked'
      ).length
      const totalCount = pagination.value.totalCount > 0 ? pagination.value.totalCount : list.length

      // 2. 生成统计结果
      statistics.value = {
        totalCount,
        draftCount,
        publishedCount,
        revokedCount,
        unreadCount: unreadCount.value
      }
    }

    /**
     * 同步公告到列表与当前详情
     */
    const syncAnnouncement = (announcement: TenantAnnouncementDto, insertIfMissing: boolean) => {
      // 1. 同步公告列表
      const index = announcements.value.findIndex((item) => item.id === announcement.id)
      if (index >= 0) {
        announcements.value.splice(index, 1, announcement)
      } else if (insertIfMissing) {
        announcements.value = [announcement, ...announcements.value]
      }

      // 2. 同步当前详情
      currentAnnouncement.value = announcement
    }

    /**
     * 获取公告列表
     */
    const fetchAnnouncements = async (
      params: AnnouncementQueryParams,
      options?: AnnouncementActionOptions
    ) => {
      loading.value = true

      try {
        // 1. 解析作用域与租户上下文
        const scope = resolveScope(options, params)
        const tenantId =
          scope === 'tenant' ? resolveTenantId(options?.tenantId ?? params.tenantId) : null

        if (scope === 'tenant' && !tenantId) {
          ElMessage.error('未获取到租户ID，无法加载租户公告')
          return null
        }

        // 2. 拉取公告列表数据
        let result: PagedResult<TenantAnnouncementDto>
        if (scope === 'app') {
          result = await appAnnouncementApi.list(params)
        } else if (scope === 'tenant' && tenantId) {
          result = await tenantAnnouncementApi.list(tenantId, params)
        } else {
          result = await platformAnnouncementApi.list(params)
        }

        // 3. 更新列表与分页状态
        applyPagedResult(result)

        // 4. 刷新统计数据
        refreshStatistics()

        return result
      } catch (error) {
        // 1. 处理异常提示
        return handleActionError(error, '获取公告列表失败', options)
      } finally {
        // 1. 关闭加载状态
        loading.value = false
      }
    }

    /**
     * 获取公告详情
     */
    const fetchAnnouncementDetail = async (
      announcementId: string,
      options?: AnnouncementActionOptions
    ) => {
      loading.value = true

      try {
        // 1. 解析作用域与租户上下文
        const scope = resolveScope(options)
        const tenantId = scope === 'tenant' ? resolveTenantId(options?.tenantId) : null

        if (scope === 'tenant' && !tenantId) {
          ElMessage.error('未获取到租户ID，无法加载公告详情')
          return null
        }

        if (scope === 'app') {
          const cached = announcements.value.find((item) => item.id === announcementId) || null
          currentAnnouncement.value = cached
          return cached
        }

        // 2. 拉取公告详情数据
        const result =
          scope === 'tenant' && tenantId
            ? await tenantAnnouncementApi.detail(tenantId, announcementId)
            : await platformAnnouncementApi.detail(announcementId)

        // 3. 同步详情数据
        syncAnnouncement(result, true)

        return result
      } catch (error) {
        // 1. 处理异常提示
        return handleActionError(error, '获取公告详情失败', options)
      } finally {
        // 1. 关闭加载状态
        loading.value = false
      }
    }

    /**
     * 创建公告
     */
    const createAnnouncement = async (
      data: AnnouncementFormData,
      options?: AnnouncementActionOptions
    ) => {
      loading.value = true

      try {
        // 1. 解析作用域与租户上下文
        const scope = resolveScope(options)
        const tenantId = scope === 'tenant' ? resolveTenantId(options?.tenantId) : null

        if (scope === 'app') {
          ElMessage.error('应用端不支持创建公告')
          return null
        }

        if (scope === 'tenant' && !tenantId) {
          ElMessage.error('未获取到租户ID，无法创建公告')
          return null
        }

        // 2. 构建请求体并发起请求
        const payload = buildCreatePayload(data as AnnouncementRequestData) as AnnouncementFormData
        const result =
          scope === 'tenant' && tenantId
            ? await tenantAnnouncementApi.create(tenantId, payload)
            : await platformAnnouncementApi.create(payload)

        // 3. 同步列表与统计
        syncAnnouncement(result, true)
        pagination.value.totalCount += 1
        pagination.value.totalPages = Math.max(
          1,
          Math.ceil(pagination.value.totalCount / pagination.value.pageSize)
        )
        refreshStatistics()

        return result
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '创建公告失败'))
        return null
      } finally {
        // 1. 关闭加载状态
        loading.value = false
      }
    }

    /**
     * 更新公告（仅草稿）
     */
    const updateAnnouncement = async (
      announcementId: string,
      data: AnnouncementFormData,
      options?: AnnouncementActionOptions
    ) => {
      loading.value = true

      try {
        // 1. 校验并发控制版本
        if (!data.rowVersion) {
          ElMessage.error('缺少并发控制版本，无法更新公告')
          return null
        }

        // 2. 解析作用域与租户上下文
        const scope = resolveScope(options)
        const tenantId = scope === 'tenant' ? resolveTenantId(options?.tenantId) : null

        if (scope === 'app') {
          ElMessage.error('应用端不支持更新公告')
          return null
        }

        if (scope === 'tenant' && !tenantId) {
          ElMessage.error('未获取到租户ID，无法更新公告')
          return null
        }

        // 3. 构建请求体并发起请求
        const payload = buildUpdatePayload(data as AnnouncementRequestData) as AnnouncementFormData
        const result =
          scope === 'tenant' && tenantId
            ? await tenantAnnouncementApi.update(tenantId, announcementId, payload)
            : await platformAnnouncementApi.update(announcementId, payload)

        // 4. 同步列表与统计
        syncAnnouncement(result, true)
        refreshStatistics()

        return result
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '更新公告失败'))
        return null
      } finally {
        // 1. 关闭加载状态
        loading.value = false
      }
    }

    /**
     * 发布公告
     */
    const publishAnnouncement = async (
      announcementId: string,
      rowVersion: string,
      options?: AnnouncementActionOptions
    ) => {
      loading.value = true

      try {
        // 1. 校验并发控制版本
        if (!rowVersion) {
          ElMessage.error('缺少并发控制版本，无法发布公告')
          return null
        }

        // 2. 解析作用域与租户上下文
        const scope = resolveScope(options)
        const tenantId = scope === 'tenant' ? resolveTenantId(options?.tenantId) : null

        if (scope === 'app') {
          ElMessage.error('应用端不支持发布公告')
          return null
        }

        if (scope === 'tenant' && !tenantId) {
          ElMessage.error('未获取到租户ID，无法发布公告')
          return null
        }

        // 3. 发起发布请求
        const result =
          scope === 'tenant' && tenantId
            ? await tenantAnnouncementApi.publish(tenantId, announcementId, { rowVersion })
            : await platformAnnouncementApi.publish(announcementId, { rowVersion })

        // 4. 同步列表与统计
        syncAnnouncement(result, true)
        refreshStatistics()

        return result
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '发布公告失败'))
        return null
      } finally {
        // 1. 关闭加载状态
        loading.value = false
      }
    }

    /**
     * 撤销公告
     */
    const revokeAnnouncement = async (
      announcementId: string,
      rowVersion: string,
      options?: AnnouncementActionOptions
    ) => {
      loading.value = true

      try {
        // 1. 校验并发控制版本
        if (!rowVersion) {
          ElMessage.error('缺少并发控制版本，无法撤销公告')
          return null
        }

        // 2. 解析作用域与租户上下文
        const scope = resolveScope(options)
        const tenantId = scope === 'tenant' ? resolveTenantId(options?.tenantId) : null

        if (scope === 'app') {
          ElMessage.error('应用端不支持撤销公告')
          return null
        }

        if (scope === 'tenant' && !tenantId) {
          ElMessage.error('未获取到租户ID，无法撤销公告')
          return null
        }

        // 3. 发起撤销请求
        const result =
          scope === 'tenant' && tenantId
            ? await tenantAnnouncementApi.revoke(tenantId, announcementId, { rowVersion })
            : await platformAnnouncementApi.revoke(announcementId, { rowVersion })

        // 4. 同步列表与统计
        syncAnnouncement(result, true)
        refreshStatistics()

        return result
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '撤销公告失败'))
        return null
      } finally {
        // 1. 关闭加载状态
        loading.value = false
      }
    }

    /**
     * 删除公告
     */
    const deleteAnnouncement = async (
      announcementId: string,
      options?: AnnouncementActionOptions
    ) => {
      loading.value = true

      try {
        // 1. 解析作用域与租户上下文
        const scope = resolveScope(options)
        const tenantId = scope === 'tenant' ? resolveTenantId(options?.tenantId) : null

        if (scope !== 'tenant') {
          ElMessage.error('仅租户公告支持删除操作')
          return false
        }

        if (!tenantId) {
          ElMessage.error('未获取到租户ID，无法删除公告')
          return false
        }

        // 2. 发起删除请求
        const result = await tenantAnnouncementApi.delete(tenantId, announcementId)

        // 3. 同步列表与统计
        announcements.value = announcements.value.filter((item) => item.id !== announcementId)
        if (currentAnnouncement.value?.id === announcementId) {
          currentAnnouncement.value = null
        }
        pagination.value.totalCount = Math.max(0, pagination.value.totalCount - 1)
        pagination.value.totalPages = Math.max(
          0,
          Math.ceil(pagination.value.totalCount / pagination.value.pageSize)
        )
        refreshStatistics()

        return result
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '删除公告失败'))
        return false
      } finally {
        // 1. 关闭加载状态
        loading.value = false
      }
    }

    /**
     * 标记公告已读
     */
    const markAsRead = async (announcementId: string, options?: AnnouncementActionOptions) => {
      if (!options?.skipLoading) {
        loading.value = true
      }

      try {
        // 1. 解析作用域与租户上下文
        const scope = options?.scope ?? 'app'
        const tenantId = scope === 'tenant' ? resolveTenantId(options?.tenantId) : null

        if (scope === 'platform') {
          if (!options?.silent) {
            ElMessage.error('平台公告不支持已读标记')
          }
          return null
        }

        if (scope === 'tenant' && !tenantId) {
          if (!options?.silent) {
            ElMessage.error('未获取到租户ID，无法标记已读')
          }
          return null
        }

        // 2. 发起标记请求
        const result =
          scope === 'tenant' && tenantId
            ? await tenantAnnouncementApi.markRead(tenantId, announcementId)
            : await appAnnouncementApi.markRead(announcementId)

        // 3. 同步列表与统计
        const wasUnread =
          announcements.value.find((item) => item.id === announcementId)?.isRead === false
        syncAnnouncement(result, true)
        if (wasUnread && unreadCount.value > 0) {
          unreadCount.value -= 1
        }
        refreshStatistics()

        return result
      } catch (error) {
        // 1. 处理异常提示
        if (!options?.silent) {
          ElMessage.error(resolveErrorMessage(error, '标记已读失败'))
        }
        return null
      } finally {
        // 1. 关闭加载状态
        if (!options?.skipLoading) {
          loading.value = false
        }
      }
    }

    /**
     * 批量标记已读
     */
    const batchMarkAsRead = async (
      announcementIds: string[],
      options?: AnnouncementActionOptions
    ) => {
      loading.value = true

      try {
        // 1. 校验参数
        if (!announcementIds.length) {
          ElMessage.warning('未选择需要标记的公告')
          return 0
        }

        // 2. 执行批量标记
        const tasks = announcementIds.map((id) =>
          markAsRead(id, { ...options, silent: true, skipLoading: true })
        )
        const results = await Promise.allSettled(tasks)
        const successCount = results.filter(
          (item) => item.status === 'fulfilled' && item.value
        ).length

        // 3. 同步未读数量
        if (successCount < announcementIds.length) {
          ElMessage.warning('部分公告标记失败，请检查网络或权限')
        }

        return successCount
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '批量标记已读失败'))
        return 0
      } finally {
        // 1. 关闭加载状态
        loading.value = false
      }
    }

    /**
     * 获取未读数量
     */
    const fetchUnreadCount = async () => {
      try {
        // 1. 拉取未读列表并读取总数
        const result = await appAnnouncementApi.unread({ page: 1, pageSize: 1 })
        unreadCount.value = Number.isNaN(result.totalCount)
          ? result.items.length
          : result.totalCount

        // 2. 刷新统计
        refreshStatistics()

        return unreadCount.value
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '获取未读数量失败'))
        return 0
      }
    }

    /**
     * 获取统计数据
     */
    const fetchStatistics = async () => {
      try {
        // 1. 基于当前列表刷新统计
        refreshStatistics()

        return statistics.value
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '获取统计数据失败'))
        return null
      }
    }

    /**
     * 保存草稿
     */
    const saveDraft = (data: Partial<AnnouncementFormData>) => {
      try {
        // 1. 准备草稿基础信息
        const draftId = currentDraft.value?.draftId ?? createDraftId()
        const lastSaved = new Date().toISOString()

        // 2. 合并草稿数据
        const draft: AnnouncementDraft = {
          ...(currentDraft.value || {}),
          ...data,
          draftId,
          lastSaved
        }

        // 3. 持久化到本地存储
        const storageKey = getDraftStorageKey(draftId)
        localStorage.setItem(storageKey, JSON.stringify(draft))
        currentDraft.value = draft

        return draft
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '保存草稿失败'))
        return null
      }
    }

    /**
     * 加载草稿
     */
    const loadDraft = (draftId: string) => {
      try {
        // 1. 读取本地存储
        const storageKey = getDraftStorageKey(draftId)
        const raw = localStorage.getItem(storageKey)
        if (!raw) {
          currentDraft.value = null
          return null
        }

        // 2. 解析草稿数据
        const draft = JSON.parse(raw) as AnnouncementDraft
        currentDraft.value = draft

        return draft
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '加载草稿失败'))
        return null
      }
    }

    /**
     * 清除草稿
     */
    const clearDraft = (draftId: string) => {
      try {
        // 1. 删除本地存储
        const storageKey = getDraftStorageKey(draftId)
        localStorage.removeItem(storageKey)

        // 2. 同步内存状态
        if (currentDraft.value?.draftId === draftId) {
          currentDraft.value = null
        }
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '清除草稿失败'))
      }
    }

    /**
     * 自动保存草稿（定时 + 防抖）
     */
    const autoSaveDraft = (data: Partial<AnnouncementFormData>, interval: number) => {
      // 1. 清理旧定时器
      if (draftAutoSaveTimer) {
        clearInterval(draftAutoSaveTimer)
        draftAutoSaveTimer = null
      }

      if (draftDebounceTimer) {
        clearTimeout(draftDebounceTimer)
        draftDebounceTimer = null
      }

      // 2. 触发防抖保存
      const scheduleSave = () => {
        // 1. 清理旧防抖定时器
        if (draftDebounceTimer) {
          clearTimeout(draftDebounceTimer)
        }

        // 2. 设置新防抖定时器
        draftDebounceTimer = setTimeout(() => {
          saveDraft(data)
        }, DEFAULT_DEBOUNCE_MS)
      }

      scheduleSave()

      // 3. 启动定时器
      const delay =
        Number.isFinite(interval) && interval > 0 ? interval : DEFAULT_AUTO_SAVE_INTERVAL
      draftAutoSaveTimer = setInterval(() => scheduleSave(), delay)

      return () => {
        if (draftAutoSaveTimer) {
          clearInterval(draftAutoSaveTimer)
          draftAutoSaveTimer = null
        }

        if (draftDebounceTimer) {
          clearTimeout(draftDebounceTimer)
          draftDebounceTimer = null
        }
      }
    }

    /**
     * 预估受众人数
     */
    const estimateAudience = async (rules: TargetRules): Promise<AudienceEstimate> => {
      try {
        // 1. 受众预估接口尚未对接，返回空结果
        const estimate: AudienceEstimate = {
          count: 0,
          preview: []
        }

        if (Object.keys(rules || {}).length > 0) {
          ElMessage.warning('受众预估接口暂未接入，请联系后端补齐')
        }

        return estimate
      } catch (error) {
        // 1. 处理异常提示
        ElMessage.error(resolveErrorMessage(error, '预估受众失败'))
        return { count: 0, preview: [] }
      }
    }

    return {
      announcements,
      currentAnnouncement,
      unreadCount,
      statistics,
      pagination,
      loading,
      currentDraft,
      hasUnread,
      draftPublishedAnnouncements,
      effectiveAnnouncements,
      fetchAnnouncements,
      fetchAnnouncementDetail,
      createAnnouncement,
      updateAnnouncement,
      publishAnnouncement,
      revokeAnnouncement,
      deleteAnnouncement,
      markAsRead,
      batchMarkAsRead,
      fetchUnreadCount,
      fetchStatistics,
      saveDraft,
      loadDraft,
      clearDraft,
      autoSaveDraft,
      estimateAudience
    }
  },
  {
    // 使用 storeId 走全局 StorageKeyManager（避免硬编码 Key）
    persist: {
      pick: ['unreadCount', 'statistics']
    }
  }
)
