import { create } from 'zustand'; import { getEvents, getEventStats, toLegacyEvent, type PredictionEvent, type EventStats, type LegacyEventRecord, } from '@/services/event'; /** @deprecated LegacyEventRecord 대신 PredictionEvent 사용 권장 */ export type { LegacyEventRecord as EventRecord } from '@/services/event'; interface EventStore { /** 원본 API 이벤트 목록 */ rawEvents: PredictionEvent[]; /** 하위 호환용 레거시 형식 이벤트 */ events: LegacyEventRecord[]; /** 상태별 통계 */ stats: EventStats; /** 페이지네이션 */ totalElements: number; totalPages: number; currentPage: number; pageSize: number; /** 로딩/에러 */ loading: boolean; error: string | null; loaded: boolean; /** API 호출 */ load: (params?: { level?: string; status?: string; category?: string; page?: number; size?: number }) => Promise; /** 화면 깜박임 없는 백그라운드 갱신 (loading 상태 변경 없음) */ silentRefresh: (params?: { level?: string; status?: string; category?: string; page?: number; size?: number }) => Promise; loadStats: () => Promise; filterByLevel: (level: string | null) => LegacyEventRecord[]; } export const useEventStore = create((set, get) => ({ rawEvents: [], events: [], stats: {}, totalElements: 0, totalPages: 0, currentPage: 0, pageSize: 20, loading: false, error: null, loaded: false, load: async (params) => { // 중복 호출 방지 (파라미터 없는 기본 호출은 loaded 체크) if (!params && get().loaded && !get().error) return; set({ loading: true, error: null }); try { const res = await getEvents(params); const legacy = res.content.map(toLegacyEvent); set({ rawEvents: res.content, events: legacy, totalElements: res.totalElements, totalPages: res.totalPages, currentPage: res.number, pageSize: res.size, loaded: true, loading: false, }); } catch (err) { set({ error: err instanceof Error ? err.message : String(err), loading: false }); } }, silentRefresh: async (params) => { try { const res = await getEvents(params); const legacy = res.content.map(toLegacyEvent); set({ rawEvents: res.content, events: legacy, totalElements: res.totalElements, totalPages: res.totalPages, currentPage: res.number, pageSize: res.size, }); } catch { // silent: 에러 무시 — 다음 갱신에서 재시도 } }, loadStats: async () => { try { const stats = await getEventStats(); set({ stats }); } catch { // stats 로딩 실패는 무시 (KPI 카드만 빈 값) } }, filterByLevel: (level) => { const { events } = get(); if (!level) return events; return events.filter((e) => e.level === level); }, }));