import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/scripture.dart';
import '../models/cycle_entry.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<ScriptureState> {
  final ScriptureDatabase _scriptureDatabase;

  ScriptureNotifier(this._scriptureDatabase) : 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<void> 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<ScriptureNotifier, ScriptureState>((ref) {
  return ScriptureNotifier(ref.watch(scriptureDatabaseProvider));
});
