import 'dart:math'; import 'package:shared_preferences/shared_preferences.dart'; import '../data/words_data.dart'; import '../models/history_entry_model.dart'; import '../models/word_model.dart'; class WordsRepository { static final WordsRepository _instance = WordsRepository._internal(); factory WordsRepository() => _instance; WordsRepository._internal(); static const String _kHistoryKey = 'oracle_999_sessions_history_v2'; List _sessionWords = []; final List _sessions = []; List get allWords => List.unmodifiable(_sessionWords); List get sessions => List.unmodifiable(_sessions); List get history => sessions; // Alias for compatibility int get totalWords => _sessionWords.length; Future init() async { // 1. Initialize random session mapping _initializeSessionMapping(); // 2. Load stored session history await _loadHistoryFromPrefs(); } void _initializeSessionMapping() { final list = List.from(kRussianTop1000Words); final random = Random(); // Fisher-Yates shuffle for (int i = list.length - 1; i > 0; i--) { int n = random.nextInt(i + 1); final temp = list[i]; list[i] = list[n]; list[n] = temp; } _sessionWords = []; for (int i = 0; i < list.length; i++) { _sessionWords.add(list[i].copyWith(sessionNumber: i)); } } void reshuffleSessionNumbers() { _initializeSessionMapping(); } WordItem? getWordBySessionNumber(int number) { if (number < 0 || number >= _sessionWords.length) return null; return _sessionWords[number]; } WordItem getRandomWord() { final random = Random(); final idx = random.nextInt(_sessionWords.length); return _sessionWords[idx]; } WordItem getNextWord(int currentSessionNumber) { int nextNumber = (currentSessionNumber + 1) % _sessionWords.length; return _sessionWords[nextNumber]; } WordItem getPreviousWord(int currentSessionNumber) { int prevNumber = (currentSessionNumber - 1 + _sessionWords.length) % _sessionWords.length; return _sessionWords[prevNumber]; } List search(String query) { query = query.trim().toLowerCase(); if (query.isEmpty) return []; final number = int.tryParse(query); if (number != null && number >= 0 && number < _sessionWords.length) { return [_sessionWords[number]]; } final exact = []; final startsWith = []; final contains = []; for (final w in _sessionWords) { final lower = w.word.toLowerCase(); if (lower == query) { exact.add(w); } else if (lower.startsWith(query)) { startsWith.add(w); } else if (lower.contains(query) || w.description.toLowerCase().contains(query) || w.category.toLowerCase().contains(query) || w.partOfSpeech.toLowerCase().contains(query)) { contains.add(w); } } return [...exact, ...startsWith, ...contains]; } List getCategories() { final set = {'Все'}; for (final w in _sessionWords) { if (w.category.isNotEmpty) { set.add(w.category); } } return set.toList(); } List getPartsOfSpeech() { final set = {'Все'}; for (final w in _sessionWords) { if (w.partOfSpeech.isNotEmpty) { set.add(w.partOfSpeech); } } return set.toList(); } // --- Session History Management --- Future saveSession(OracleSession session) async { final existingIdx = _sessions.indexWhere((s) => s.id == session.id); if (existingIdx != -1) { _sessions[existingIdx] = session; } else { _sessions.insert(0, session); } if (_sessions.length > 500) { _sessions.removeRange(500, _sessions.length); } await _saveHistoryToPrefs(); } // Backward compatibility alias Future addHistoryEntry(OracleSession entry) => saveSession(entry); Future updateSession(String id, {String? aiInterpretation, String? question}) async { final idx = _sessions.indexWhere((e) => e.id == id); if (idx != -1) { final old = _sessions[idx]; _sessions[idx] = old.copyWith( aiInterpretation: aiInterpretation ?? old.aiInterpretation, question: question ?? old.question, ); await _saveHistoryToPrefs(); } } Future updateHistoryEntry(String id, {String? aiInterpretation, String? question}) => updateSession(id, aiInterpretation: aiInterpretation, question: question); Future deleteSession(String id) async { _sessions.removeWhere((e) => e.id == id); await _saveHistoryToPrefs(); } Future deleteHistoryEntry(String id) => deleteSession(id); Future clearHistory() async { _sessions.clear(); await _saveHistoryToPrefs(); } Future _loadHistoryFromPrefs() async { try { final prefs = await SharedPreferences.getInstance(); final jsonList = prefs.getStringList(_kHistoryKey); _sessions.clear(); if (jsonList != null) { for (final item in jsonList) { try { _sessions.add(OracleSession.fromJson(item)); } catch (_) {} } } } catch (_) {} } Future _saveHistoryToPrefs() async { try { final prefs = await SharedPreferences.getInstance(); final jsonList = _sessions.map((e) => e.toJson()).toList(); await prefs.setStringList(_kHistoryKey, jsonList); } catch (_) {} } }