import 'dart:async';
import 'dart:math' as math;
import 'dart:ui' as ui;
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:aesthetica_wallpaper/models/drag_puzzle_game.dart';

class DragPuzzleProvider extends ChangeNotifier {
  DragPuzzleGame? _currentGame;
  Timer? _timer;

  DragPuzzleGame? get currentGame => _currentGame;

  /// 创建拖拽式拼图游戏
  Future<void> createDragPuzzle({
    required String imagePath,
    required DragPuzzleDifficulty difficulty,
  }) async {
    // 停止之前的计时器
    _timer?.cancel();

    // 分割图片
    final pieces = await _splitImageForDrag(
      imagePath,
      difficulty.rows,
      difficulty.cols,
    );

    // 打乱拼图块顺序
    pieces.shuffle();

    // 创建游戏
    _currentGame = DragPuzzleGame(
      pieces: pieces,
      gridRows: difficulty.rows,
      gridCols: difficulty.cols,
      imagePath: imagePath,
    );

    // 开始计时
    _startTimer();

    notifyListeners();
  }

  /// 分割图片为拖拽式拼图块
  Future<List<DragPuzzlePiece>> _splitImageForDrag(
    String imagePath,
    int rows,
    int cols,
  ) async {
    final pieces = <DragPuzzlePiece>[];

    // 加载图片
    final ByteData data = await rootBundle.load(imagePath);
    final codec = await ui.instantiateImageCodec(data.buffer.asUint8List());
    final frame = await codec.getNextFrame();
    final image = frame.image;

    final pieceWidth = image.width ~/ cols;
    final pieceHeight = image.height ~/ rows;

    // 分割图片
    for (int row = 0; row < rows; row++) {
      for (int col = 0; col < cols; col++) {
        final id = row * cols + col;

        // 创建图片块
        final recorder = ui.PictureRecorder();
        final canvas = Canvas(recorder);

        canvas.drawImageRect(
          image,
          Rect.fromLTWH(
            col * pieceWidth.toDouble(),
            row * pieceHeight.toDouble(),
            pieceWidth.toDouble(),
            pieceHeight.toDouble(),
          ),
          Rect.fromLTWH(0, 0, pieceWidth.toDouble(), pieceHeight.toDouble()),
          Paint(),
        );

        final picture = recorder.endRecording();
        final pieceImage = await picture.toImage(pieceWidth, pieceHeight);

        // 将图片转换为字节数据
        final byteData = await pieceImage.toByteData(
          format: ui.ImageByteFormat.png,
        );
        final uint8List = byteData!.buffer.asUint8List();

        pieces.add(
          DragPuzzlePiece(
            id: id,
            correctRow: row,
            correctCol: col,
            image: MemoryImage(uint8List),
          ),
        );
      }
    }

    return pieces;
  }

  /// 将拼图块放置到指定位置
  void placePiece(int pieceId, int targetRow, int targetCol) {
    if (_currentGame == null || _currentGame!.isComplete) return;

    final pieces = List<DragPuzzlePiece>.from(_currentGame!.pieces);
    final pieceIndex = pieces.indexWhere((p) => p.id == pieceId);

    if (pieceIndex == -1) return;

    final piece = pieces[pieceIndex];

    // 检查目标位置是否已被占用
    final existingPiece = _currentGame!.getPieceAt(targetRow, targetCol);
    if (existingPiece != null) {
      // 如果目标位置有其他块，将其移回底部
      final existingIndex = pieces.indexWhere((p) => p.id == existingPiece.id);
      pieces[existingIndex] = existingPiece.copyWith(
        isPlaced: false,
        currentRow: null,
        currentCol: null,
      );
    }

    // 放置当前块
    pieces[pieceIndex] = piece.copyWith(
      isPlaced: true,
      currentRow: targetRow,
      currentCol: targetCol,
    );

    // 增加移动次数
    final newMoves = _currentGame!.moves + 1;

    // 更新游戏状态
    _currentGame = _currentGame!.copyWith(pieces: pieces, moves: newMoves);

    // 检查是否完成
    if (_currentGame!.checkComplete()) {
      _completeGame();
    }

    notifyListeners();
  }

  /// 将拼图块移回底部
  void removePiece(int pieceId) {
    if (_currentGame == null || _currentGame!.isComplete) return;

    final pieces = List<DragPuzzlePiece>.from(_currentGame!.pieces);
    final pieceIndex = pieces.indexWhere((p) => p.id == pieceId);

    if (pieceIndex == -1) return;

    final piece = pieces[pieceIndex];

    // 只有已放置的块才能移除
    if (!piece.isPlaced) return;

    pieces[pieceIndex] = piece.copyWith(
      isPlaced: false,
      currentRow: null,
      currentCol: null,
    );

    _currentGame = _currentGame!.copyWith(
      pieces: pieces,
      moves: _currentGame!.moves + 1,
    );

    notifyListeners();
  }

  /// 开始计时
  void _startTimer() {
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (_currentGame != null && !_currentGame!.isComplete) {
        _currentGame = _currentGame!.copyWith(
          elapsedTime: _currentGame!.elapsedTime + const Duration(seconds: 1),
        );
        notifyListeners();
      }
    });
  }

  /// 完成游戏
  void _completeGame() {
    _timer?.cancel();
    _currentGame = _currentGame!.copyWith(isComplete: true);
  }

  /// 重新开始游戏
  void restartGame() {
    if (_currentGame == null) return;

    _timer?.cancel();

    // 重置所有拼图块
    final pieces = _currentGame!.pieces
        .map(
          (piece) => piece.copyWith(
            isPlaced: false,
            currentRow: null,
            currentCol: null,
          ),
        )
        .toList();

    // 重新打乱
    pieces.shuffle();

    _currentGame = _currentGame!.copyWith(
      pieces: pieces,
      elapsedTime: Duration.zero,
      moves: 0,
      isComplete: false,
    );

    _startTimer();
    notifyListeners();
  }

  /// 提示功能
  void showHint() {
    if (_currentGame == null || _currentGame!.isComplete) return;

    // 找到第一个未正确放置的块
    final unplacedPieces = _currentGame!.unplacedPieces;
    if (unplacedPieces.isNotEmpty) {
      final hintPiece = unplacedPieces.first;
      print(
        '提示：将块 ${hintPiece.id} 放到位置 (${hintPiece.correctRow}, ${hintPiece.correctCol})',
      );
    }
  }

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