import 'dart:async';
import 'package:flutter/material.dart';
import 'package:service_api/service_api.dart';
import 'package:function_tree/function_tree.dart';
import 'math_quiz_generator.dart';
import '../models/math_quiz_models.dart';
import '../models/math_quiz_difficulty.dart'; // 👈 MathQuizDifficulty 정의 필요

class MathQuizController with ChangeNotifier {
  late final MathQuizDifficulty difficulty;
  late final String userId;
  late final String? userName;

  late MathQuizPuzzle puzzle;
  late List<String?> _userAnswers;
  List<String?> get userAnswers => _userAnswers;

  int _selectedBlankIndex = 0;
  int get selectedBlankIndex => _selectedBlankIndex;

  bool _isGameCompleted = false;
  bool get isGameCompleted => _isGameCompleted;

  Timer? _timer;
  int _secondsElapsed = 0;
  int get secondsElapsed => _secondsElapsed;

  late final int _totalPuzzlesInLevel;
  int _currentPuzzleIndex = 0;
  int get totalPuzzlesInLevel => _totalPuzzlesInLevel;
  int get currentPuzzleIndex => _currentPuzzleIndex;

  bool _isWrongAnswer = false;
  bool get isWrongAnswer => _isWrongAnswer;

  int _totalBlanksFilled = 0;
  int get totalBlanksFilled => _totalBlanksFilled;

  int _remainingTries = 3;
  int get remainingTries => _remainingTries;

  bool _isRevealingAnswer = false;
  bool get isRevealingAnswer => _isRevealingAnswer;

  /// 현재 선택된 빈칸의 타입을 반환
  PuzzleBlankType? get currentSelectedBlankType {
    if (puzzle.blankTypes.isEmpty ||
        _selectedBlankIndex < 0 ||
        _selectedBlankIndex >= puzzle.blankTypes.length) {
      return null;
    }
    return puzzle.blankTypes[_selectedBlankIndex];
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  void _startTimer() {
    _timer?.cancel();
    _secondsElapsed = 0;
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      _secondsElapsed++;
      notifyListeners();
    });
  }

  void _stopTimer() {
    _timer?.cancel();
  }

  void startNewGame(MathQuizDifficulty level, String userId, String? userName) {
    this.difficulty = level;
    this.userId = userId;
    this.userName = userName;
    _totalPuzzlesInLevel = level.puzzleCount;
    _currentPuzzleIndex = 0;
    _isGameCompleted = false;
    _totalBlanksFilled = 0;
    _loadNextPuzzle();
    _startTimer();
    notifyListeners();
  }

  /// [🔥 수정] 문제 로드 시 로그 추가
  void _loadNextPuzzle() {
    final generator = MathQuizGenerator();
    this.puzzle = generator.generatePuzzle(difficulty);

    // --- [LOG: 문제 구조 확인] ---
    debugPrint("--- MATH QUIZ PUZZLE LOADED (${difficulty.contextId}) ---");
    debugPrint("Grid: ${puzzle.gridCells}");
    debugPrint("Solutions (S): ${puzzle.solutions}");
    debugPrint("Blank Types (T): ${puzzle.blankTypes}");
    debugPrint("Total Blanks: ${puzzle.solutions.length}");
    debugPrint("------------------------------------------");
    // ----------------------------

    _userAnswers = List.generate(puzzle.solutions.length, (_) => null);
    _selectedBlankIndex = 0;
    _isWrongAnswer = false;
    _remainingTries = 3;
    _isRevealingAnswer = false;
  }

  /// [🔥 수정] 빈칸 선택 시 로그 추가
  void onBlankTapped(int index) {
    if (_isGameCompleted || _isRevealingAnswer) return;
    if (_selectedBlankIndex != index) {
      _selectedBlankIndex = index;
      
      // --- [LOG: 선택된 빈칸 타입 확인] ---
      final selectedType = currentSelectedBlankType?.toString() ?? 'None/Invalid';
      debugPrint("[LOG] BLANK TAPPED: Index $index selected.");
      debugPrint("[LOG] BLANK TAPPED: Determined Type: $selectedType");
      // ----------------------------------

      notifyListeners();
    }
  }

  void onOptionTapped(String option) {
    if (_isGameCompleted || _isRevealingAnswer) return;
    _isWrongAnswer = false;

    if (_selectedBlankIndex >= puzzle.blankTypes.length) return;
    final PuzzleBlankType requiredType = puzzle.blankTypes[_selectedBlankIndex];
    final bool isOptionNumber = int.tryParse(option) != null;
    final bool isOptionOperator = ['+', '-', '*', '/'].contains(option);

    if (requiredType == PuzzleBlankType.number && !isOptionNumber) {
      return;
    }
    if (requiredType == PuzzleBlankType.operator && !isOptionOperator) {
      return;
    }

    if (_selectedBlankIndex < _userAnswers.length) {
      _userAnswers[_selectedBlankIndex] = option;
    }

    _selectNextBlank();
    notifyListeners();
    _checkCompletion();
  }

  void onClearTapped() {
    if (_isGameCompleted || _isRevealingAnswer) return;
    _isWrongAnswer = false;
    if (_selectedBlankIndex < _userAnswers.length) {
      _userAnswers[_selectedBlankIndex] = null;
    }
    notifyListeners();
  }

  void _selectNextBlank() {
    if (_userAnswers.isEmpty) return;
    int nextIndex = (_selectedBlankIndex + 1) % _userAnswers.length;
    for (int i = 0; i < _userAnswers.length; i++) {
      if (_userAnswers[nextIndex] == null) {
        _selectedBlankIndex = nextIndex;
        return;
      }
      nextIndex = (nextIndex + 1) % _userAnswers.length;
    }
  }

  void _checkCompletion() {
    if (_userAnswers.any((answer) => answer == null)) {
      _isWrongAnswer = false;
      return;
    }
    bool fastMatch = true;
    for (int i = 0; i < puzzle.solutions.length; i++) {
      if (_userAnswers[i] != puzzle.solutions[i]) {
        fastMatch = false;
        break;
      }
    }
    if (fastMatch) {
      _handleCorrectAnswer();
      return;
    }
    bool slowMatch = _checkSlowPathValidation();
    if (slowMatch) {
      _handleCorrectAnswer();
    } else {
      _handleWrongAnswer();
    }
  }

  bool _checkSlowPathValidation() {
    List<String> rebuiltGrid = List.of(puzzle.gridCells);
    int answerIndex = 0;
    for (int i = 0; i < rebuiltGrid.length; i++) {
      if (rebuiltGrid[i] == '?') {
        if (answerIndex < _userAnswers.length) {
          rebuiltGrid[i] = _userAnswers[answerIndex]!;
          answerIndex++;
        }
      }
    }
    try {
      for (final eq in puzzle.equations) {
        final String expression =
            eq.expressionIndices.map((i) => rebuiltGrid[i]).join(' ');
        final String expectedResultStr = rebuiltGrid[eq.resultIndex];
        if (expression.contains('=') ||
            expectedResultStr.contains(RegExp(r'[+\-*/]'))) {
          return false;
        }
        final num actualResult = expression.interpret();
        final num expectedResult = num.parse(expectedResultStr);
        if (actualResult != expectedResult) {
          return false;
        }
      }
      return true;
    } catch (e) {
      debugPrint("방정식 평가 실패: $e");
      return false;
    }
  }

  void _handleCorrectAnswer() {
    _isWrongAnswer = false;
    _totalBlanksFilled += _userAnswers.length;
    if (_currentPuzzleIndex + 1 < _totalPuzzlesInLevel) {
      _currentPuzzleIndex++;
      _loadNextPuzzle();
      notifyListeners();
    } else {
      _isGameCompleted = true;
      _stopTimer();
      notifyListeners();
    }
  }

  void _handleWrongAnswer() {
    _remainingTries--;
    _isWrongAnswer = true;
    if (_remainingTries <= 0) {
      _handleFailedAnswer();
    } else {
      notifyListeners();
    }
  }

  void _handleFailedAnswer() {
    _isWrongAnswer = false;
    _isRevealingAnswer = true;
    _userAnswers = List.of(puzzle.solutions);
    notifyListeners();
    Future.delayed(const Duration(seconds: 3), () {
      if (!_isGameCompleted) {
        if (_currentPuzzleIndex + 1 < _totalPuzzlesInLevel) {
          _currentPuzzleIndex++;
          _loadNextPuzzle();
          notifyListeners();
        } else {
          _isGameCompleted = true;
          _stopTimer();
          notifyListeners();
        }
      }
    });
  }
}