import { useReducer, useEffect, useMemo } from 'react' import { INITIAL_TEST_ITEMS, TestItem, CardState, sortTestItemsByPriority, generateVocabOptions, SIMPLE_CARDS } from '@/lib/data/reviewSimpleData' interface ReviewState { testItems: TestItem[] score: { correct: number; total: number } isComplete: boolean } type ReviewAction = | { type: 'LOAD_PROGRESS'; payload: ReviewState } | { type: 'ANSWER_TEST_ITEM'; payload: { testItemId: string; confidence: number } } | { type: 'SKIP_TEST_ITEM'; payload: { testItemId: string } } | { type: 'RESTART' } // 內部測驗項目更新函數 const updateTestItem = ( testItems: TestItem[], testItemId: string, updates: Partial ): TestItem[] => { return testItems.map((item) => item.id === testItemId ? { ...item, ...updates } : item ) } const reviewReducer = (state: ReviewState, action: ReviewAction): ReviewState => { switch (action.type) { case 'LOAD_PROGRESS': return action.payload case 'ANSWER_TEST_ITEM': { const { testItemId, confidence } = action.payload const isCorrect = confidence >= 1 // 修正:一般(1分)以上都算答對 const testItem = state.testItems.find(item => item.id === testItemId) if (!testItem) return state // 修正:只有答對才標記為完成,答錯只增加錯誤次數 const updatedTestItems = updateTestItem(state.testItems, testItemId, isCorrect ? { isCompleted: true } // 答對:標記完成 : { wrongCount: testItem.wrongCount + 1 } // 答錯:只增加錯誤次數,不完成 ) const newScore = { correct: state.score.correct + (isCorrect ? 1 : 0), total: state.score.total + 1 } const remainingTestItems = updatedTestItems.filter(item => !item.isCompleted) const isComplete = remainingTestItems.length === 0 return { testItems: updatedTestItems, score: newScore, isComplete } } case 'SKIP_TEST_ITEM': { const { testItemId } = action.payload const testItem = state.testItems.find(item => item.id === testItemId) if (!testItem) return state const updatedTestItems = updateTestItem(state.testItems, testItemId, { skipCount: testItem.skipCount + 1 }) const remainingTestItems = updatedTestItems.filter(item => !item.isCompleted) const isComplete = remainingTestItems.length === 0 return { testItems: updatedTestItems, score: state.score, isComplete } } case 'RESTART': return { testItems: INITIAL_TEST_ITEMS, score: { correct: 0, total: 0 }, isComplete: false } default: return state } } export function useReviewSession() { // 使用 useReducer 統一狀態管理 const [state, dispatch] = useReducer(reviewReducer, { testItems: INITIAL_TEST_ITEMS, score: { correct: 0, total: 0 }, isComplete: false }) const { testItems, score, isComplete } = state // 智能排序獲取當前測驗項目 - 使用 useMemo 優化性能 const sortedTestItems = useMemo(() => sortTestItemsByPriority(testItems), [testItems]) const incompleteTestItems = useMemo(() => sortedTestItems.filter((item: TestItem) => !item.isCompleted), [sortedTestItems] ) const currentTestItem = incompleteTestItems[0] // 總是選擇優先級最高的未完成測驗項目 const currentCard = currentTestItem?.cardData // 當前詞卡數據 // localStorage進度保存和載入 useEffect(() => { // 載入保存的進度 const savedProgress = localStorage.getItem('review-linear-progress') if (savedProgress) { try { const parsed = JSON.parse(savedProgress) const saveTime = new Date(parsed.timestamp) const now = new Date() const isToday = saveTime.toDateString() === now.toDateString() if (isToday && parsed.testItems) { dispatch({ type: 'LOAD_PROGRESS', payload: { testItems: parsed.testItems, score: parsed.score || { correct: 0, total: 0 }, isComplete: parsed.isComplete || false } }) console.log('📖 載入保存的線性複習進度') } } catch (error) { console.warn('進度載入失敗:', error) localStorage.removeItem('review-linear-progress') } } }, []) // 保存進度到localStorage const saveProgress = () => { const progress = { testItems, score, isComplete, timestamp: new Date().toISOString() } localStorage.setItem('review-linear-progress', JSON.stringify(progress)) console.log('💾 線性進度已保存') } // 處理測驗項目答題 const handleAnswer = (confidence: number) => { if (!currentTestItem) return dispatch({ type: 'ANSWER_TEST_ITEM', payload: { testItemId: currentTestItem.id, confidence } }) // 保存進度 setTimeout(() => saveProgress(), 100) } // 處理測驗項目跳過 const handleSkip = () => { if (!currentTestItem) return dispatch({ type: 'SKIP_TEST_ITEM', payload: { testItemId: currentTestItem.id } }) // 保存進度 setTimeout(() => saveProgress(), 100) } // 重新開始 - 重置所有狀態 const handleRestart = () => { dispatch({ type: 'RESTART' }) localStorage.removeItem('review-linear-progress') console.log('🔄 線性複習進度已重置') } // 生成詞彙選擇選項 (僅當當前是詞彙選擇測驗時) const vocabOptions = useMemo(() => { if (currentTestItem?.testType === 'vocab-choice' && currentCard) { return generateVocabOptions(currentCard.word, SIMPLE_CARDS) } return [] }, [currentTestItem, currentCard]) return { // 狀態 testItems, score, isComplete, currentTestItem, currentCard, vocabOptions, sortedTestItems, // 計算屬性 totalTestItems: testItems.length, completedTestItems: testItems.filter(item => item.isCompleted).length, // 動作 handleAnswer, handleSkip, handleRestart } }