// ============================================================
// useAnnouncements — 公告轮询 + 未读缓存 Hook
//
// 行为：
//   - 挂载时立即拉取公告列表
//   - 之后每 15 分钟自动轮询
//   - 通过 localStorage 缓存已读公告 ID，跨会话持久化
//   - 提供 markAsRead() 在用户查看后清除未读标记
// ============================================================

import { useState, useEffect, useCallback, useRef } from 'react';
import { fetchAnnouncements, type Announcement } from '@/modules/announcement/controllers/announcement-api';
import { logger } from '@/shared/utils/bus';

const SEEN_IDS_KEY = 'heixiu:announcement:seen-ids';
const POLL_INTERVAL = 15 * 60 * 1000; // 15 分钟

// ---------- 缓存工具 ----------

function loadSeenIds(): Set<number> {
    try {
        const raw = localStorage.getItem(SEEN_IDS_KEY);
        if (!raw) return new Set();
        const arr: number[] = JSON.parse(raw);
        return new Set(arr.filter((n) => typeof n === 'number'));
    } catch {
        return new Set();
    }
}

function saveSeenIds(ids: Set<number>): void {
    try {
        localStorage.setItem(SEEN_IDS_KEY, JSON.stringify([...ids]));
    } catch {
        /* localStorage 写入失败 — 静默降级，下次会话重新计数 */
    }
}

// ---------- Hook ----------

export interface AnnouncementsState {
    /** 当前活跃公告列表 */
    announcements: Announcement[];
    /** 未读公告数量 */
    unreadCount: number;
    /** 是否正在加载 */
    loading: boolean;
    /** 标记全部已读（打开抽屉时调用） */
    markAsRead: () => void;
}

export function useAnnouncements(): AnnouncementsState {
    const [announcements, setAnnouncements] = useState<Announcement[]>([]);
    const [unreadCount, setUnreadCount] = useState(0);
    const [loading, setLoading] = useState(false);
    const seenRef = useRef<Set<number>>(loadSeenIds());

    const fetchAndCompare = useCallback(async () => {
        setLoading(true);
        try {
            const data = await fetchAnnouncements();
            const active = data.filter((item) => item.is_active);
            setAnnouncements(active);
            const newIds = active.filter((item) => !seenRef.current.has(item.id));
            setUnreadCount(newIds.length);
        } catch (err) {
            logger.warn('ui', '公告轮询失败', err instanceof Error ? err : new Error(String(err)));
        } finally {
            setLoading(false);
        }
    }, []);

    // 挂载时首次拉取 + 每 15 分钟定时轮询
    useEffect(() => {
        fetchAndCompare();
        const timer = setInterval(fetchAndCompare, POLL_INTERVAL);
        return () => clearInterval(timer);
    }, [fetchAndCompare]);

    // 标记全部已读：将当前公告 ID 写入缓存
    const markAsRead = useCallback(() => {
        announcements.forEach((item) => seenRef.current.add(item.id));
        saveSeenIds(seenRef.current);
        setUnreadCount(0);
    }, [announcements]);

    return { announcements, unreadCount, loading, markAsRead };
}
