import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:making_school_asignment_app/common/utils/cached_network_img.dart';

/// [url] 图片地址
/// [viewWidth] 视图宽度
/// [viewHeight] 视图高度
/// [imageDisplayHeight] 图片显示高度
/// [onTrans] 位置变化回调
/// [onScale] 缩放变化回调
/// [onContentOffset] 内容偏移变化回调
/// [transformationController] 变换控制器 作用于外部更新调整内部数据的缩放和位置
class ZoomView extends HookWidget {
  final String url;
  final double viewWidth;
  final double viewHeight;
  final double imageDisplayHeight;
  final Function(Offset)? onTrans;
  final Function(double)? onScale;
  final Function(Offset)? onContentOffset;
  final TransformationController? transformationController;

  const ZoomView({
    required this.url,
    required this.viewWidth,
    required this.viewHeight,
    required this.imageDisplayHeight,
    this.onTrans,
    this.onScale,
    this.onContentOffset,
    this.transformationController,
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    final controller = transformationController ?? useTransformationController();

    useEffect(() {
      double? lastScale;
      Offset? lastOffset;
      Offset? lastContentOffset;

      void notifyIfChanged() {
        final matrix = controller.value;
        final scale = matrix.getMaxScaleOnAxis();
        final translation = matrix.getTranslation();
        final offset = Offset(translation.x, translation.y);

        // 只在 scale 变化时回调（浮点误差容忍）
        if (onScale != null && (lastScale == null || (lastScale! - scale).abs() > 0.001)) {
          onScale!(scale);
          lastScale = scale;
        }
        // 只在 offset 变化时回调（浮点误差容忍）
        if (onTrans != null && (lastOffset == null || (lastOffset! - offset).distance > 0.5)) {
          onTrans!(offset);
          lastOffset = offset;
        }
        // 只在内容偏移变化时回调（浮点误差容忍）
        if (onContentOffset != null) {
          final scaledHeight = imageDisplayHeight * scale;
          final dx = translation.x;
          double dy = viewHeight > scaledHeight ? (viewHeight - scaledHeight) / 2.0 : 0;
          dy += translation.y;
          final contentOffset = Offset(dx, dy);
          if (lastContentOffset == null || (lastContentOffset! - contentOffset).distance > 0.5) {
            onContentOffset!(contentOffset);
            lastContentOffset = contentOffset;
          }
        }

        // 内容小于视图时，放大后拖动自动回弹，内容始终不溢出
        // final scaledHeight = imageDisplayHeight * scale;
        // if (imageDisplayHeight < viewHeight && scaledHeight <= viewHeight) {
        //   final centerY = (viewHeight - scaledHeight) / 2.0;
        //   if ((translation.y - centerY).abs() > 0.5 || translation.x.abs() > 0.5) {
        //     final newMatrix = Matrix4.identity()
        //       ..translate(0.0, centerY)
        //       ..scale(scale);
        //     controller.value = newMatrix;
        //   }
        // }
      }

      controller.addListener(notifyIfChanged);
      return () {
        controller.removeListener(notifyIfChanged);
      };
    }, [controller, imageDisplayHeight, viewHeight]);

    return InteractiveViewer(
      minScale: 1,
      maxScale: 2.0,
      panEnabled: true,
      constrained: imageDisplayHeight < viewHeight,
      transformationController: controller,
      clipBehavior: Clip.antiAliasWithSaveLayer,
      child: Center(
        child: $TheCachedNetworkImage(
          imageUrl: url,
          imgWidth: viewWidth,
          (_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth),
        ),
      ),
    );
  }
}
