import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../models/word_model.dart'; import '../models/vocabulary_book_model.dart'; import '../models/study_session_model.dart'; import '../models/daily_stats_model.dart'; import '../services/vocabulary_service.dart'; import '../../../core/network/api_client.dart'; import '../../../core/services/storage_service.dart'; import '../services/learning_stats_service.dart'; import '../models/learning_stats_model.dart'; /// 词汇状态 class VocabularyState { final bool isLoading; final String? error; final List systemBooks; final List userBooks; final List> categories; final List todayWords; final List reviewWords; final StudyStatistics? todayStatistics; final StudySession? currentSession; final DailyStats? dailyStats; final Map? overallStats; final int weeklyWordsStudied; const VocabularyState({ this.isLoading = false, this.error, this.systemBooks = const [], this.userBooks = const [], this.categories = const [], this.todayWords = const [], this.reviewWords = const [], this.todayStatistics, this.currentSession, this.dailyStats, this.overallStats, this.weeklyWordsStudied = 0, }); VocabularyState copyWith({ bool? isLoading, String? error, List? systemBooks, List? userBooks, List>? categories, List? todayWords, List? reviewWords, StudyStatistics? todayStatistics, StudySession? currentSession, DailyStats? dailyStats, Map? overallStats, int? weeklyWordsStudied, }) { return VocabularyState( isLoading: isLoading ?? this.isLoading, error: error, systemBooks: systemBooks ?? this.systemBooks, userBooks: userBooks ?? this.userBooks, categories: categories ?? this.categories, todayWords: todayWords ?? this.todayWords, reviewWords: reviewWords ?? this.reviewWords, todayStatistics: todayStatistics ?? this.todayStatistics, currentSession: currentSession ?? this.currentSession, dailyStats: dailyStats ?? this.dailyStats, overallStats: overallStats ?? this.overallStats, weeklyWordsStudied: weeklyWordsStudied ?? this.weeklyWordsStudied, ); } } /// 词汇状态管理 class VocabularyNotifier extends StateNotifier { final VocabularyService _vocabularyService; VocabularyNotifier(this._vocabularyService) : super(const VocabularyState()); /// 加载系统词汇书 Future loadSystemVocabularyBooks({ VocabularyBookDifficulty? difficulty, String? category, }) async { try { state = state.copyWith(isLoading: true, error: null); final books = await _vocabularyService.getSystemVocabularyBooks( difficulty: difficulty, category: category, limit: 100, // 加载所有词汇书 ); state = state.copyWith( isLoading: false, systemBooks: books, ); } catch (e) { state = state.copyWith( isLoading: false, error: e.toString(), ); } } /// 加载词汇书分类 Future loadVocabularyBookCategories() async { try { state = state.copyWith(isLoading: true, error: null); final categories = await _vocabularyService.getVocabularyBookCategories(); state = state.copyWith( isLoading: false, categories: categories, ); } catch (e) { state = state.copyWith( isLoading: false, error: e.toString(), ); } } /// 加载用户词汇书 Future loadUserVocabularyBooks() async { try { state = state.copyWith(isLoading: true, error: null); final books = await _vocabularyService.getUserVocabularyBooks(); state = state.copyWith( isLoading: false, userBooks: books, ); } catch (e) { state = state.copyWith( isLoading: false, error: e.toString(), ); } } /// 加载今日学习单词 Future loadTodayStudyWords({String? userId}) async { try { state = state.copyWith(isLoading: true, error: null); final words = await _vocabularyService.getTodayStudyWords(); print('今日单词加载完成,数量: ${words.length}'); StudyStatistics statistics; try { statistics = await _vocabularyService.getStudyStatistics(DateTime.now()); print('学习统计加载成功: wordsStudied=${statistics.wordsStudied}, newWords=${statistics.newWordsLearned}'); } catch (e) { print('学习统计加载失败: $e,使用默认值'); // 接口不可用时,构造默认的今日统计 final now = DateTime.now(); final correct = (words.length * 0.8).round(); final wrong = words.length - correct; statistics = StudyStatistics( id: 'local_${now.toIso8601String().split('T').first}', userId: 'current_user', date: now, sessionCount: 1, wordsStudied: words.length, newWordsLearned: words.length, wordsReviewed: 0, wordsMastered: 0, totalStudyTimeSeconds: words.length * 30, correctAnswers: correct, wrongAnswers: wrong, averageAccuracy: words.isEmpty ? 0.0 : correct / (correct + wrong), experienceGained: words.length * 5, pointsGained: words.length * 2, streakDays: 1, ); } // 额外加载每日词汇统计(wordsLearned、studyTimeMinutes) DailyStats? dailyStats; if (userId != null && userId.isNotEmpty) { try { dailyStats = await _vocabularyService.getDailyVocabularyStats(userId: userId); print('每日词汇统计加载成功: wordsLearned=${dailyStats.wordsLearned}'); } catch (e) { print('每日词汇统计加载失败: $e'); // ignore, 使用StudyStatistics中的wordsStudied作为兜底 dailyStats = DailyStats( wordsLearned: statistics.wordsStudied, studyTimeMinutes: (statistics.totalStudyTimeSeconds / 60).round(), ); } } state = state.copyWith( isLoading: false, todayWords: words, todayStatistics: statistics, dailyStats: dailyStats, ); print('状态更新完成: todayWords=${words.length}, statistics.wordsStudied=${statistics.wordsStudied}'); } catch (e) { print('loadTodayStudyWords失败: $e'); state = state.copyWith( isLoading: false, error: e.toString(), ); } } /// 加载用户词汇整体统计(总学习词汇数、准确率等) Future loadUserVocabularyOverallStats() async { try { state = state.copyWith(isLoading: true, error: null); final stats = await _vocabularyService.getUserVocabularyStats(); print('整体统计加载成功: $stats'); state = state.copyWith(isLoading: false, overallStats: stats); } catch (e) { print('整体统计加载失败: $e'); state = state.copyWith(isLoading: false, error: e.toString()); } } /// 加载本周学习统计(累计学习单词数) Future loadWeeklyStudyStats() async { try { final now = DateTime.now(); final startOfWeek = now.subtract(Duration(days: now.weekday - 1)); // 周一 final endOfWeek = startOfWeek.add(const Duration(days: 6)); // 周日 print('加载本周统计: $startOfWeek 到 $endOfWeek'); final list = await _vocabularyService.getStudyStatisticsHistory( startDate: DateTime(startOfWeek.year, startOfWeek.month, startOfWeek.day), endDate: DateTime(endOfWeek.year, endOfWeek.month, endOfWeek.day), ); print('本周统计数据: ${list.length} 天'); final total = list.fold(0, (sum, s) => sum + (s.wordsStudied)); print('本周累计学习: $total 个单词'); state = state.copyWith(weeklyWordsStudied: total); } catch (e) { print('本周统计加载失败: $e'); // 出错时保持为0 } } /// 加载复习单词 Future loadReviewWords() async { try { state = state.copyWith(isLoading: true, error: null); final words = await _vocabularyService.getReviewWords(); state = state.copyWith( isLoading: false, reviewWords: words, ); } catch (e) { state = state.copyWith( isLoading: false, error: e.toString(), ); } } /// 添加词汇书到用户 Future addVocabularyBookToUser(String bookId) async { try { await _vocabularyService.addVocabularyBookToUser(bookId); // 重新加载用户词汇书 await loadUserVocabularyBooks(); } catch (e) { state = state.copyWith(error: e.toString()); } } /// 开始学习会话 Future startStudySession({ required StudyMode mode, String? vocabularyBookId, required int targetWordCount, }) async { try { state = state.copyWith(isLoading: true, error: null); final session = await _vocabularyService.startStudySession( mode: mode, vocabularyBookId: vocabularyBookId, targetWordCount: targetWordCount, ); state = state.copyWith( isLoading: false, currentSession: session, ); } catch (e) { state = state.copyWith( isLoading: false, error: e.toString(), ); } } /// 结束学习会话 Future endStudySession({ required String sessionId, required int durationSeconds, required List exercises, }) async { try { await _vocabularyService.endStudySession( sessionId, durationSeconds: durationSeconds, exercises: exercises, ); state = state.copyWith(currentSession: null); // 重新加载今日数据 await loadTodayStudyWords(); } catch (e) { state = state.copyWith(error: e.toString()); } } /// 更新单词学习进度 Future updateWordProgress({ required String wordId, required LearningStatus status, required bool isCorrect, int responseTime = 0, }) async { try { await _vocabularyService.updateUserWordProgress( wordId: wordId, status: status, isCorrect: isCorrect, responseTime: responseTime, ); } catch (e) { state = state.copyWith(error: e.toString()); } } /// 清除错误 void clearError() { state = state.copyWith(error: null); } } /// 词汇服务提供者 final vocabularyServiceProvider = FutureProvider((ref) async { final apiClient = ApiClient.instance; final storageService = await StorageService.getInstance(); return VocabularyService( apiClient: apiClient, storageService: storageService, ); }); /// 词汇状态提供者(使用 StateNotifierProvider 以支持状态更新) final vocabularyProvider = StateNotifierProvider.autoDispose((ref) { // 同步创建 Notifier,延迟加载数据 final vocabularyService = ref.watch(vocabularyServiceProvider).value; if (vocabularyService == null) { // 如果服务未就绪,返回空状态的 Notifier throw Exception('词汇服务未就绪'); } final notifier = VocabularyNotifier(vocabularyService); // 在后台异步加载系统词汇书和分类 Future.wait([ notifier.loadSystemVocabularyBooks(), notifier.loadVocabularyBookCategories(), ]); return notifier; }); /// 当前学习会话提供者 final currentStudySessionProvider = Provider((ref) { final state = ref.watch(vocabularyProvider); return state.currentSession; }); /// 今日学习统计提供者 final todayStatisticsProvider = Provider((ref) { final state = ref.watch(vocabularyProvider); return state.todayStatistics; }); /// 每日词汇统计提供者 final dailyVocabularyStatsProvider = Provider((ref) { final state = ref.watch(vocabularyProvider); return state.dailyStats; }); /// 用户词汇整体统计提供者 final overallVocabularyStatsProvider = Provider?>( (ref) { final state = ref.watch(vocabularyProvider); return state.overallStats; }, ); /// 本周累计学习单词数提供者 final weeklyWordsStudiedProvider = Provider((ref) { final state = ref.watch(vocabularyProvider); return state.weeklyWordsStudied; }); /// 用户词汇书提供者 final userVocabularyBooksProvider = Provider>((ref) { final state = ref.watch(vocabularyProvider); return state.userBooks; }); /// 系统词汇书提供者 final systemVocabularyBooksProvider = Provider>((ref) { final state = ref.watch(vocabularyProvider); return state.systemBooks; }); /// 今日单词提供者 final todayWordsProvider = Provider>((ref) { final state = ref.watch(vocabularyProvider); return state.todayWords; }); /// 复习单词提供者 final reviewWordsProvider = Provider>((ref) { final state = ref.watch(vocabularyProvider); return state.reviewWords; }); /// 词汇书学习统计 class BookStudyStats { final String bookId; final int studyDays; final double averageAccuracy; const BookStudyStats({ required this.bookId, required this.studyDays, required this.averageAccuracy, }); } /// 学习统计服务提供者 final learningStatsServiceProvider = FutureProvider((ref) async { final apiClient = ApiClient.instance; final storageService = await StorageService.getInstance(); return LearningStatsService(apiClient: apiClient, storageService: storageService); }); /// 用户学习统计提供者 final learningStatsProvider = FutureProvider((ref) async { final service = await ref.watch(learningStatsServiceProvider.future); return service.getUserStats(); }); /// 指定词汇书的学习统计(学习天数、平均准确率) final bookStudyStatsProvider = FutureProvider.autoDispose.family((ref, bookId) async { final service = await ref.watch(learningStatsServiceProvider.future); final records = await service.getDailyRecords(); final filtered = records.where((r) => r.vocabularyBookIds.contains(bookId)).toList(); final studyDays = filtered.length; double avgAccuracy = 0.0; if (filtered.isNotEmpty) { final totalWeight = filtered.fold(0, (sum, r) => sum + (r.wordsLearned + r.wordsReviewed)); if (totalWeight > 0) { final weightedSum = filtered.fold(0.0, (sum, r) => sum + r.accuracyRate * (r.wordsLearned + r.wordsReviewed)); avgAccuracy = weightedSum / totalWeight; } else { avgAccuracy = filtered.fold(0.0, (sum, r) => sum + r.accuracyRate) / filtered.length; } } return BookStudyStats(bookId: bookId, studyDays: studyDays, averageAccuracy: avgAccuracy); }); /// 词汇书学习进度(百分比、已学/已掌握数量) final vocabularyBookProgressProvider = FutureProvider.autoDispose.family((ref, bookId) async { final service = await ref.watch(vocabularyServiceProvider.future); return service.getVocabularyBookProgress(bookId); });