# 狀態管理系統文件

## 📋 概述

這個目錄包含了應用程式的狀態管理系統，採用 **Zustand** 作為狀態管理工具。系統被設計為模組化架構，將原本單一巨大的 store 拆分為多個專門化的 stores，每個都有明確的職責範圍。

## 🏗️ 架構設計

### 設計原則
- **單一職責原則**: 每個 store 只負責特定的狀態域
- **最小重渲染**: 組件只訂閱需要的狀態，避免不必要的重渲染
- **型別安全**: 使用 TypeScript 確保型別安全
- **可測試性**: 小型、專注的 stores 更容易測試

### Store 分類
```
/store/
├── useReviewSessionStore.ts    # 會話狀態管理
├── useTestQueueStore.ts        # 測試隊列管理
├── useTestResultStore.ts       # 測試結果管理
├── useReviewDataStore.ts       # 數據狀態管理
└── useUIStore.ts              # UI 狀態管理
```

## 📚 各 Store 詳細說明

### 1. useReviewSessionStore.ts
**職責**: 管理複習會話的核心狀態

#### 狀態內容
```typescript
interface ReviewSessionState {
  // 核心會話狀態
  mounted: boolean              // 組件是否已掛載
  isLoading: boolean           // 是否正在載入
  error: string | null         // 錯誤訊息

  // 當前卡片狀態
  currentCard: ExtendedFlashcard | null  // 當前顯示的詞卡
  currentCardIndex: number               // 當前卡片索引
}
```

#### 主要功能
- **會話生命週期管理**: 控制會話的開始、結束
- **當前卡片追蹤**: 追蹤使用者正在學習的詞卡
- **錯誤處理**: 統一管理會話相關錯誤

#### 使用範例
```typescript
const { currentCard, error, setCurrentCard } = useReviewSessionStore()

// 設置當前卡片
setCurrentCard(newCard)
```

---

### 2. useTestQueueStore.ts
**職責**: 管理測試隊列和測試流程

#### 狀態內容
```typescript
interface TestQueueState {
  testItems: TestItem[]        // 測試項目清單
  currentTestIndex: number     // 當前測試索引
  completedTests: number       // 已完成測試數量
  totalTests: number          // 總測試數量
  currentMode: ReviewMode     // 當前測試模式
}
```

#### 主要功能
- **測試隊列初始化**: 根據詞卡和已完成測試建立隊列
- **測試進度管理**: 追蹤測試進度和完成狀態
- **測試流程控制**: 控制測試的前進、跳過等操作

#### 核心方法
```typescript
// 初始化測試隊列
initializeTestQueue(dueCards, completedTests)

// 進入下一個測試
goToNextTest()

// 跳過當前測試
skipCurrentTest()

// 標記測試完成
markTestCompleted(testIndex)
```

#### 測試類型
- `flip-memory`: 翻卡記憶
- `vocab-choice`: 詞彙選擇
- `vocab-listening`: 詞彙聽力
- `sentence-listening`: 例句聽力
- `sentence-fill`: 例句填空
- `sentence-reorder`: 例句重組
- `sentence-speaking`: 例句口說

---

### 3. useTestResultStore.ts
**職責**: 管理測試結果和分數統計

#### 狀態內容
```typescript
interface TestResultState {
  score: { correct: number; total: number }  // 分數統計
  isRecordingResult: boolean                 // 是否正在記錄結果
  recordingError: string | null             // 記錄錯誤
}
```

#### 主要功能
- **分數追蹤**: 記錄正確和總答題數
- **結果記錄**: 將測試結果發送到後端
- **統計計算**: 提供準確率等統計資訊

#### 核心方法
```typescript
// 更新分數
updateScore(isCorrect: boolean)

// 記錄測試結果到後端
recordTestResult({
  flashcardId,
  testType,
  isCorrect,
  userAnswer,
  confidenceLevel,
  responseTimeMs
})

// 獲取準確率
getAccuracyPercentage()
```

---

### 4. useReviewDataStore.ts
**職責**: 管理複習數據和UI顯示狀態

#### 狀態內容
```typescript
interface ReviewDataState {
  dueCards: ExtendedFlashcard[]  // 到期詞卡清單
  showComplete: boolean          // 是否顯示完成畫面
  showNoDueCards: boolean       // 是否顯示無詞卡畫面
  isLoadingCards: boolean       // 是否正在載入詞卡
  loadingError: string | null   // 載入錯誤
}
```

#### 主要功能
- **詞卡資料管理**: 載入和管理到期的詞卡
- **UI 狀態控制**: 控制不同UI狀態的顯示
- **資料快取**: 快取詞卡資料避免重複請求

#### 核心方法
```typescript
// 載入到期詞卡
loadDueCards()

// 根據ID查找詞卡
findCardById(cardId)

// 獲取詞卡數量
getDueCardsCount()
```

---

### 5. useUIStore.ts
**職責**: 管理全域UI狀態

#### 狀態內容
```typescript
interface UIState {
  showTaskListModal: boolean     // 任務清單Modal
  showReportModal: boolean       // 錯誤回報Modal
  modalImage: string | null      // 圖片Modal
  reportReason: string          // 回報原因
  reportingCard: any | null     // 正在回報的詞卡
  isAutoSelecting: boolean      // 自動選擇狀態
}
```

## 🔄 Store 之間的協作

### 資料流向
```mermaid
graph TD
    A[useReviewDataStore] -->|詞卡資料| B[useTestQueueStore]
    B -->|當前測試| C[useReviewSessionStore]
    C -->|測試互動| D[useTestResultStore]
    D -->|結果回饋| B
    E[useUIStore] -.->|UI狀態| A
    E -.->|UI狀態| B
    E -.->|UI狀態| C
    E -.->|UI狀態| D
```

### 協作流程
1. **初始化階段**:
   - `useReviewDataStore` 載入到期詞卡
   - `useTestQueueStore` 根據詞卡建立測試隊列
   - `useReviewSessionStore` 設置當前詞卡

2. **測試階段**:
   - `useReviewSessionStore` 管理當前測試狀態
   - `useTestResultStore` 記錄測試結果
   - `useTestQueueStore` 控制測試進度

3. **完成階段**:
   - `useTestQueueStore` 檢查是否完成所有測試
   - `useReviewDataStore` 顯示完成狀態

## 🎯 使用最佳實踐

### 1. 選擇性訂閱
```typescript
// ❌ 避免：訂閱整個 store
const store = useReviewSessionStore()

// ✅ 推薦：只訂閱需要的狀態
const { currentCard, error } = useReviewSessionStore()
```

### 2. 狀態更新模式
```typescript
// ✅ 推薦：使用專門的 actions
const { setCurrentCard } = useReviewSessionStore()
setCurrentCard(newCard)

// ❌ 避免：直接修改狀態
// store.currentCard = newCard  // 這樣不會觸發重渲染
```

### 3. 錯誤處理
```typescript
// ✅ 推薦：檢查錯誤狀態
const { error, isLoading } = useReviewSessionStore()

if (error) {
  return <ErrorComponent message={error} />
}

if (isLoading) {
  return <LoadingComponent />
}
```

## 🧪 測試策略

### 單元測試
```typescript
// 測試 store 的 actions
describe('useTestResultStore', () => {
  it('should update score correctly', () => {
    const { updateScore, score } = useTestResultStore.getState()

    updateScore(true)
    expect(score.correct).toBe(1)
    expect(score.total).toBe(1)
  })
})
```

### 整合測試
```typescript
// 測試多個 stores 的協作
describe('Review Flow Integration', () => {
  it('should coordinate between stores correctly', () => {
    // 測試資料載入 → 隊列建立 → 測試執行的流程
  })
})
```

## 🔧 開發工具

### Zustand DevTools
```typescript
import { subscribeWithSelector, devtools } from 'zustand/middleware'

export const useReviewSessionStore = create<ReviewSessionState>()(
  devtools(
    subscribeWithSelector((set, get) => ({
      // store implementation
    })),
    { name: 'review-session-store' }
  )
)
```

## 📈 效能考量

### 重渲染優化
- **狀態分離**: 不相關的狀態變更不會觸發組件重渲染
- **選擇性訂閱**: 組件只訂閱需要的狀態片段
- **記憶化**: 使用 `useMemo` 和 `useCallback` 優化計算

### 記憶體管理
- **自動清理**: stores 會在適當時機重置狀態
- **垃圾回收**: 移除不再需要的資料引用

## 🚀 未來擴展

### 新增 Store
1. 建立新的 store 檔案
2. 定義 interface 和初始狀態
3. 實作 actions 和 getters
4. 加入適當的 TypeScript 型別
5. 更新文件

### Store 拆分指導原則
- 當 store 超過 150 行時考慮拆分
- 根據業務邏輯邊界進行拆分
- 確保拆分後的 stores 職責清晰

---

## 📞 支援

如有問題或需要協助，請參考：
- [Zustand 官方文件](https://zustand-demo.pmnd.rs/)
- [TypeScript 最佳實踐](https://www.typescriptlang.org/docs/)
- 團隊內部技術文件

**維護者**: 開發團隊
**最後更新**: 2025-09-28