import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../core/network/dio_client.dart';
import '../../data/datasources/quiz_remote_datasource.dart';
import '../../data/repositories/quiz_repository_impl.dart';
import 'quiz_state.dart';

class QuizCubit extends Cubit<QuizState> {
  final QuizRepositoryImpl _repo;

  QuizCubit()
      : _repo = QuizRepositoryImpl(QuizRemoteDatasource(DioClient.instance)),
        super(const QuizSetup());

  Future<void> loadFilters() async {
    emit(const QuizSetup(isLoadingFilters: true));
    try {
      final filters = await _repo.getFilters();
      emit(QuizSetup(filters: filters));
    } catch (e) {
      emit(QuizSetup(filters: const FilterOptionsModel()));
    }
  }

  Future<void> startQuiz({
    required int numQuestions,
    String? difficulty,
    String? category,
  }) async {
    emit(const QuizStarting());
    try {
      final response = await _repo.startQuiz(
        numQuestions: numQuestions,
        difficulty: difficulty,
        category: category,
      );
      emit(QuizActive(
        questions: response.questions,
        currentIndex: 0,
        userAnswers: List.filled(response.questions.length, null),
        currentRevealed: false,
        attemptId: response.attemptId,
      ));
    } catch (e) {
      emit(QuizError(e.toString()));
    }
  }

  void selectAnswer(String label) {
    final s = state;
    if (s is! QuizActive || s.currentRevealed) return;

    final newAnswers = List<String?>.from(s.userAnswers);
    newAnswers[s.currentIndex] = label;

    emit(s.copyWith(
      userAnswers: newAnswers,
      currentRevealed: true,
    ));
  }

  void nextQuestion() {
    final s = state;
    if (s is! QuizActive || s.isLastQuestion) return;

    emit(s.copyWith(
      currentIndex: s.currentIndex + 1,
      currentRevealed: s.userAnswers[s.currentIndex + 1] != null,
    ));
  }

  Future<void> submitQuiz() async {
    final s = state;
    if (s is! QuizActive) return;

    emit(const QuizSubmitting());

    try {
      // Build answer submissions — map label back to answer text
      final answers = <Map<String, String>>[];
      for (var i = 0; i < s.questions.length; i++) {
        final q = s.questions[i];
        final selectedLabel = s.userAnswers[i];
        if (selectedLabel == null) continue;

        final selectedOpt =
            q.options.where((o) => o.label == selectedLabel).firstOrNull;
        if (selectedOpt == null) continue;

        answers.add({
          'scenario_id': q.scenarioId,
          'selected_answer': selectedOpt.text,
        });
      }

      final result = await _repo.submitQuiz(
        attemptId: s.attemptId,
        answers: answers,
      );

      emit(QuizResults(
        result: result,
        questions: s.questions,
        userAnswers: s.userAnswers,
      ));
    } catch (e) {
      emit(QuizError(e.toString()));
    }
  }

  void reset() {
    emit(const QuizSetup());
    loadFilters();
  }
}