import { useState, useEffect, useCallback, useRef } from 'react'; import { getLatestBriefing, triggerLottoCurate } from '../../../api'; const normalizePicks = (picks) => { if (Array.isArray(picks)) { return { core: picks, bonus: [], extended: [], pool: [] }; } return { core: picks?.core || [], bonus: picks?.bonus || [], extended: picks?.extended || [], pool: picks?.pool || [], }; }; export default function useBriefing() { const [briefing, setBriefing] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [regenerating, setRegenerating] = useState(false); const pollingRef = useRef(null); const load = useCallback(async () => { setLoading(true); setError(''); try { const data = await getLatestBriefing(); setBriefing(data ? { ...data, picks: normalizePicks(data.picks) } : data); } catch (e) { setError(e.message); } finally { setLoading(false); } }, []); useEffect(() => { load(); }, [load]); const regenerate = useCallback(async () => { setRegenerating(true); setError(''); try { const prevGen = briefing?.generated_at; await triggerLottoCurate(); let attempts = 0; pollingRef.current = setInterval(async () => { attempts += 1; try { const data = await getLatestBriefing(); if (data && data.generated_at !== prevGen) { setBriefing({ ...data, picks: normalizePicks(data.picks) }); setRegenerating(false); clearInterval(pollingRef.current); } } catch {} if (attempts >= 40) { clearInterval(pollingRef.current); setRegenerating(false); setError('재생성 타임아웃 (2분)'); } }, 3000); } catch (e) { setError(e.message); setRegenerating(false); } }, [briefing?.generated_at]); useEffect(() => () => { if (pollingRef.current) clearInterval(pollingRef.current); }, []); return { briefing, loading, error, regenerating, reload: load, regenerate }; }