import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { deleteHistory, getHistory, recommend } from '../../../api'; import { buildMetricsFromHistory } from '../lottoUtils'; export default function useManualRecommend() { const [params, setParams] = useState({ recent_window: 200, recent_weight: 2.0, avoid_recent_k: 5, }); const presets = useMemo(() => [ { name: '기본', recent_window: 200, recent_weight: 2.0, avoid_recent_k: 5 }, { name: '최근 가중치↑', recent_window: 100, recent_weight: 3.0, avoid_recent_k: 10 }, { name: '안전(분산)', recent_window: 300, recent_weight: 1.6, avoid_recent_k: 8 }, { name: '공격(최근)', recent_window: 80, recent_weight: 3.5, avoid_recent_k: 12 }, ], []); const [result, setResult] = useState(null); const [history, setHistory] = useState([]); const [historyExpanded, setHistoryExpanded] = useState(false); const historyEndRef = useRef(null); const prevHistoryExpandedRef = useRef(false); const [loading, setLoading] = useState({ recommend: false, history: false }); const [error, setError] = useState(''); const historyMetrics = useMemo(() => buildMetricsFromHistory(history), [history]); const visibleHistory = historyExpanded ? history : history.slice(0, 5); const refreshHistory = useCallback(async () => { setLoading((s) => ({ ...s, history: true })); setError(''); try { const limit = 100; let offset = 0; const allItems = []; while (true) { const data = await getHistory(limit, offset); const items = data.items ?? []; allItems.push(...items); if (items.length < limit) break; offset += limit; } setHistory(allItems); } catch (e) { setError(e?.message ?? String(e)); } finally { setLoading((s) => ({ ...s, history: false })); } }, []); const onRecommend = useCallback(async () => { setLoading((s) => ({ ...s, recommend: true })); setError(''); try { const data = await recommend(params); setResult(data); await refreshHistory(); } catch (e) { setError(e?.message ?? String(e)); } finally { setLoading((s) => ({ ...s, recommend: false })); } }, [params, refreshHistory]); const onDelete = useCallback(async (id) => { if (!confirm(`히스토리 #${id}를 삭제할까요?`)) return; setError(''); try { await deleteHistory(id); setHistory((prev) => prev.filter((item) => item.id !== id)); } catch (e) { setError(e?.message ?? String(e)); } }, []); useEffect(() => { if (historyExpanded && !prevHistoryExpandedRef.current) { requestAnimationFrame(() => { historyEndRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' }); }); } prevHistoryExpandedRef.current = historyExpanded; }, [historyExpanded, visibleHistory.length]); useEffect(() => { refreshHistory(); }, []); // eslint-disable-line react-hooks/exhaustive-deps return { params, setParams, presets, result, history, historyExpanded, setHistoryExpanded, historyEndRef, loading, error, setError, historyMetrics, visibleHistory, refreshHistory, onRecommend, onDelete, }; }