import 'package:flutter/material.dart';
import 'package:flyinsono/lab/pages/lab_image/urm_data_processor/index.dart';
import 'package:flyinsono/lab/pages/lab_image/urm_data_processor/urm_data_processor.dart';
import 'package:flyinsono/lab/pages/lab_image/urm_data_processor/urm_enums.dart';
import 'package:flyinsono/lab/pages/lab_image/urm_data_processor/urm_visual_info.dart';
import 'package:flyinsono/lab/pages/lab_image/widgets/widgets.dart';
import 'package:flyinsono/pages/throttler.dart';
import 'package:get/get.dart';
import 'dart:math';
import 'package:fis_jsonrpc/services/researchEdition.m.dart';

class ImageTraceOverlayController extends GetxController {
  ///轨迹层视图id
  static const String imageTraceOverlayId = "image_trace_overlay";
  static const String imageTraceCanavsId = "image_trace_canvas";

  ImageTraceOverlayController({this.onTraceSelected});

  final VoidCallback? onTraceSelected;

  /// Trace 面板的 key
  final GlobalKey imageTraceLayerKey = GlobalKey();

  final Throttler throttler = Throttler(delay: Duration(milliseconds: 50));

  /// Trace 面板的渲染尺寸
  Size? roiLayerSize;

  bool isActive = false; // 是否激活

  /// 图片的宽高比（用于对齐图像）
  double aspectRatio = 16 / 9;

  // 当前的 URM 图像数据
  URMDataProcessor _urmDataProcessor = URMDataProcessor();

  // Trace 绘制状态
  TraceStatus selectStatus = TraceStatus.wating;
  // 视图参数
  RoiViewType get roiViewType => _urmDataProcessor.visualInfo.roiViewType;

  ///是否开启同步显示
  bool get isSyncDisplay => _urmDataProcessor.isSyncDisplay;
  double get beamsLeft => _urmDataProcessor.visualInfo.beamsLeftBoundary;
  double get beamsRight => _urmDataProcessor.visualInfo.beamsRightBoundary;
  double get beamsRangePercent => beamsRight - beamsLeft;
  bool get isLinear => _urmDataProcessor.visualInfo.isLinear;
  double get scanWidth => _urmDataProcessor.visualInfo.scanWidth;
  Offset get zeroCenterOffset => _urmDataProcessor.visualInfo.zeroCenterOffset;
  List<Point<double>> points = [];
  List<Point<double>> zoomPoints = [];
  Point<double>? startPoint; // 起始点
  Point<double>? endPoint; // 结束点
  /// 从左侧开始框选（用于双幅的情况）
  bool startFromLeft = true;

  void active() {
    if (isActive) return;
    isActive = true;
    update([imageTraceOverlayId]);
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      onRenderSizeChanged();
    });
  }

  void deactive() {
    if (!isActive) return;
    isActive = false;
    clearPoints();
    update([imageTraceOverlayId]);
  }

  ///清理所有点集
  void clearPoints() {
    points.clear();
    zoomPoints.clear();
    setUrmTraceDPoints();
    update([imageTraceCanavsId]);
  }

  void setUrmTraceDPoints() {
    _urmDataProcessor.setUrmTraceDPoints(zoomPoints);
  }

  /// 设置 URM 数据处理器
  void setURMDataProcessor(URMDataProcessor urmDataProcessor) {
    _urmDataProcessor = urmDataProcessor;
    update([imageTraceOverlayId]);
  }

  void setOverlaySize(int width, int height) {
    aspectRatio = width / height;
    update([imageTraceOverlayId]);
    // 下一帧再更新
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      onRenderSizeChanged();
    });
  }

  // 计算实际render的尺寸，赋值给 roiLayerSize
  void onRenderSizeChanged() {
    if (imageTraceLayerKey.currentContext == null) return;
    final RenderBox renderBox =
        imageTraceLayerKey.currentContext!.findRenderObject() as RenderBox;
    final size = renderBox.size;
    roiLayerSize = size;
  }

  void onMouseDown(Offset position) {
    switch (selectStatus) {
      case TraceStatus.wating:
        startFromLeft = isOnLeft(position);
        if (!isInValideArea(offsetToPoint(position))) {
          return;
        }
        selectStatus = TraceStatus.selecting;
        startPoint = offsetToPoint(position);
        points.clear();
        zoomPoints.clear();
        if (startPoint != null) {
          points.add(startPoint!);
          zoomPoints.add(getZoomPoint(position));
        }
        endPoint = null;
        break;
      case TraceStatus.selecting:
        final percentOffset = correctPosition(position);
        final Point<double> percentPoint = offsetToPoint(percentOffset);
        endPoint = correctBeamsBoundry(percentPoint);
        points.add(endPoint!);
        zoomPoints.add(getZoomPoint(position));
        setUrmTraceDPoints();
        onTraceSelected?.call();
        selectStatus = TraceStatus.wating;
        points.clear();
        zoomPoints.clear();
        isActive = false;
        update([imageTraceOverlayId]);
        break;
      case TraceStatus.end:
        break;
    }
  }

  void onMouseMove(Offset position) {
    throttler.run(() {
      if (selectStatus == TraceStatus.selecting) {
        final percentOffset = correctPosition(position);
        final Point<double> percentPoint = offsetToPoint(percentOffset);
        points.add(percentPoint);
        var zoomPoint = getZoomPoint(position);
        zoomPoints.add(zoomPoint);
        print("points.add: $percentPoint  zoomPoints.add $zoomPoint");
        update([imageTraceCanavsId]);
      }
    });
  }

  Point<double> getZoomPoint(Offset offset) {
    final width = (_urmDataProcessor.showLeftRight && isSyncDisplay)
        ? roiLayerSize!.width / 2
        : roiLayerSize!.width;
    final height = roiLayerSize!.height;
    final x = offset.dx / width;
    final y = offset.dy / height;
    // Rect zoomArea = _urmDataProcessor.calculator.calMeasureAreaInFullVisual(
    //     1.0, Offset(0.5, 0.5), isSyncDisplay, _urmDataProcessor.roiArea);
    Rect zoomArea = _urmDataProcessor.measureAreaInFullVisual;
    Offset percentOffset = Offset(x % 1, y);
    percentOffset =
        _urmDataProcessor.calculator.pointPctOutRect(zoomArea, percentOffset);

    return Point<double>(percentOffset.dx, percentOffset.dy);
  }

  bool isOnLeft(Offset position) {
    if (roiLayerSize == null ||
        roiLayerSize!.width == 0 ||
        roiLayerSize!.height == 0) {
      return false;
    }
    final double x = position.dx / roiLayerSize!.width;
    print("startFromLeft: ${x < 0.5}");
    return x < 0.5;
  }

  // 是否在有效区域
  bool isInValideArea(Point<double> point) {
    double x = point.x;
    if (isSyncDisplay) {
      return x > beamsLeft && x < beamsRight;
    } else {
      URMVisualInfo visualInfo = _urmDataProcessor.visualInfo;
      return x > visualInfo.beamsLeftBoundary &&
          x < visualInfo.beamsRightBoundary;
    }
  }

  Point<double> offsetToPoint(Offset position) {
    if (roiLayerSize == null ||
        roiLayerSize!.width == 0 ||
        roiLayerSize!.height == 0) {
      return Point(0, 0);
    }
    final double x = position.dx / roiLayerSize!.width;
    final double y = position.dy / roiLayerSize!.height;
    if (roiViewType == RoiViewType.leftRightHalfHalf && isSyncDisplay) {
      if (startFromLeft) {
        return Point(x * 2, y);
      } else {
        return Point(x * 2 % 1, y);
      }
    }
    return correctBeamsBoundry(Point(x, y));
  }

  // 矫正位置保持在同一侧
  Offset correctPosition(Offset position) {
    if (roiLayerSize == null ||
        roiLayerSize!.width == 0 ||
        roiLayerSize!.height == 0) {
      return position;
    }
    if (isSyncDisplay) {
      final double horizontalCenetr = roiLayerSize!.width / 2;
      if (roiViewType == RoiViewType.leftRightHalfHalf) {
        if (startFromLeft) {
          return Offset(
            min(position.dx, horizontalCenetr),
            position.dy,
          );
        } else {
          return Offset(
            max(position.dx, horizontalCenetr),
            position.dy,
          );
        }
      }
    }
    return position;
  }

  // 矫正边界
  Point<double> correctBeamsBoundry(Point<double> point) {
    if (isSyncDisplay) {
      if (point.x < beamsLeft) {
        return Point(beamsLeft, point.y);
      }
      if (point.x > beamsRight) {
        return Point(beamsRight, point.y);
      }
    }
    return point;
  }
}
