import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../models/scripture.dart'; import '../models/cycle_entry.dart'; import 'user_provider.dart'; import 'package:collection/collection.dart'; // For IterableExtension // State for ScriptureProvider class ScriptureState { final Scripture? currentScripture; final CyclePhase? currentPhase; final int currentIndex; // Index within the phase-specific list final int? maxIndex; // Max number of scriptures for the current phase ScriptureState({ this.currentScripture, this.currentPhase, this.currentIndex = 0, this.maxIndex, }); ScriptureState copyWith({ Scripture? currentScripture, CyclePhase? currentPhase, int? currentIndex, int? maxIndex, }) { return ScriptureState( currentScripture: currentScripture ?? this.currentScripture, currentPhase: currentPhase ?? this.currentPhase, currentIndex: currentIndex ?? this.currentIndex, maxIndex: maxIndex ?? this.maxIndex, ); } } // StateNotifier for ScriptureProvider class ScriptureNotifier extends StateNotifier { final ScriptureDatabase _scriptureDatabase; final Ref _ref; ScriptureNotifier(this._scriptureDatabase, this._ref) : super(ScriptureState()) { // We don't initialize here directly, as we need the phase from other providers. // Initialization will be triggered by the UI. } // Initialize/refresh scripture for a given phase // This should be called by the consuming widget when the phase changes or on initial load. Future initializeScripture(CyclePhase phase) async { // Only re-initialize if the phase has changed or no scripture is currently set if (state.currentPhase != phase || state.currentScripture == null) { final scriptureCount = _scriptureDatabase.getScriptureCountForPhase(phase.name); if (scriptureCount > 0) { // Use day of year to get a stable initial scripture for the day final dayOfYear = DateTime.now().difference(DateTime(DateTime.now().year, 1, 1)).inDays; final initialIndex = dayOfYear % scriptureCount; state = state.copyWith( currentPhase: phase, currentIndex: initialIndex, maxIndex: scriptureCount, currentScripture: _scriptureDatabase.getScriptureForPhaseByIndex( phase.name, initialIndex), ); } else { state = state.copyWith( currentPhase: phase, currentScripture: null, currentIndex: 0, maxIndex: 0, ); } } } void getNextScripture() { if (state.currentPhase == null || state.maxIndex == null || state.maxIndex == 0) return; final nextIndex = (state.currentIndex + 1) % state.maxIndex!; _updateScripture(nextIndex); } void getPreviousScripture() { if (state.currentPhase == null || state.maxIndex == null || state.maxIndex == 0) return; final prevIndex = (state.currentIndex - 1 + state.maxIndex!) % state.maxIndex!; _updateScripture(prevIndex); } void getRandomScripture() { if (state.currentPhase == null || state.maxIndex == null || state.maxIndex == 0) return; // Use a proper random number generator for better randomness final randomIndex = DateTime.now().microsecondsSinceEpoch % state.maxIndex!; // Still using timestamp for simplicity _updateScripture(randomIndex); } void _updateScripture(int newIndex) { if (state.currentPhase == null) return; final newScripture = _scriptureDatabase.getScriptureForPhaseByIndex( state.currentPhase!.name, newIndex); state = state.copyWith( currentIndex: newIndex, currentScripture: newScripture, ); } } final scriptureDatabaseProvider = Provider((ref) => ScriptureDatabase()); final scriptureProvider = StateNotifierProvider((ref) { return ScriptureNotifier(ref.watch(scriptureDatabaseProvider), ref); });