import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:puzzleweave/play/board.dart';

final _log = Logger('overlayer.dart');

class HintItem {
  final ui.Image finger;
  final Rect srcRect;
  final Rect destRect;
  final CurveTween tween;

  HintItem(this.finger, this.srcRect, this.destRect) : tween = CurveTween(curve: Curves.easeInOut);

  Rect getCurrent(double t) {
    return Rect.lerp(srcRect, destRect, tween.transform(t))!;
  }

  // 动画的前 10% 和后 10% 渐入渐出，中间 80% 完全不透明
  double getOpacity(double t) {
    if (t < 0.1) {
      return t * 10;
    } else if (t >= 0.1 && t <= 0.9) {
      return 1;
    } else {
      return (1 - t) * 10;
    }
  }
}

class OverLayer {
  final Board board;
  final TickerProvider tickerProvider;
  OverlayEntry? _overlayEntry;

  final ValueNotifier<int> _notifier = ValueNotifier(0);

  late AnimationController hintAnimation;
  Listenable get notifiers => Listenable.merge([_notifier, hintAnimation]);

  OverLayer(this.board, this.tickerProvider) {
    hintAnimation = AnimationController(value: 0, vsync: tickerProvider, duration: const Duration(milliseconds: 1200));
  }

  void invalidate() {
    _notifier.value++;
  }

  void setup(BuildContext context) {
    if (_overlayEntry != null) return;

    // 创建并插入 OverlayEntry
    _overlayEntry = OverlayEntry(
      builder: (context) {
        return Positioned.fill(
          // 关键：IgnorePointer 确保手势引导动画不会阻碍底层的 BoardPlay 交互
          child: IgnorePointer(
            child: RepaintBoundary(child: CustomPaint(painter: OverLayerPainter(this))),
          ),
        );
      },
    );
    Overlay.of(context).insert(_overlayEntry!);
  }

  HintItem? _hintItem;
  HintItem? get hintItem => _hintItem;

  void doHint(HintItem hintItem) {
    ///上一次hint没有完成
    if (_hintItem != null) {
      return;
    }
    _hintItem = hintItem;
    hintAnimation.reset();
    hintAnimation.repeat(); // 重复播放动画
  }

  void stopHint() {
    if (_hintItem != null) {
      hintAnimation.stop();
      _hintItem = null;

      invalidate();
    }
  }

  bool get isHinting => _hintItem != null && hintAnimation.isAnimating;

  destroy() {
    _overlayEntry?.remove();
    hintAnimation.dispose();
  }
}

class OverLayerPainter extends CustomPainter {
  final OverLayer overLayer;

  OverLayerPainter(this.overLayer) : super(repaint: overLayer.notifiers);

  @override
  void paint(Canvas canvas, Size size) {
    // canvas.clipRect(Offset.zero & size);
    if (overLayer.hintItem != null) {
      _paintHintItem(canvas, overLayer.hintItem!);
    }
  }

  void _paintHintItem(Canvas canvas, HintItem hintItem) {
    Rect srcRect = Offset.zero & Size(hintItem.finger.width.toDouble(), hintItem.finger.height.toDouble());
    Rect currentRect = hintItem.getCurrent(overLayer.hintAnimation.value);

    // 完善点: 计算并应用透明度
    double opacity = hintItem.getOpacity(overLayer.hintAnimation.value);

    // 创建 Paint，通过 color.withOpacity 控制透明度
    final paint = Paint()
      ..color = Colors.white.withOpacity(opacity)
      ..isAntiAlias = true;

    // 绘制图片
    canvas.drawImageRect(hintItem.finger, srcRect, currentRect, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}
