import 'dart:math';
import 'dart:ui';
import 'package:fis_jsonrpc/services/researchEdition.m.dart';
import 'package:flyinsono/lab/pages/lab_image/urm_data_processor/index.dart';

abstract class IURMCalculator {
  final URMVisualInfo visualInfo; // URM 视图参数
  final int rawBeams; // 原始数据横向像素
  final int rawSamples; // 原始数据纵向像素
  final double probeWidth; // 探头宽度

  IURMCalculator({
    required this.visualInfo,
    required this.rawBeams,
    required this.rawSamples,
    required this.probeWidth,
  });

  // 根据绘制的 ROI 区域归一化数值计算 ROI 区域参数
  GridArea calROIParam(NormCoord coord);

  /// 基于 ROI 信息计算 ROI 在完整图像中的归一化坐标
  NormCoord calNormCoordInFullImage(GridArea roiArea);

  /// 基于起点终点坐标信息计算 ROI 在有效区域中的归一化坐标
  NormCoord calNormCoordInRegionByRoiPos(RoiPosRelativeToImage roiPos);

  /// 计算用于后处理的坐标信息
  ProcessPosParams calPostProcessImageParams(
    double zoomFactor,
    Offset zoomOffset,
    GridArea roiArea,
    bool syncDisplay,
  );

  /// 计算用于预览图像的坐标信息
  ProcessPosParams calPreviewImageParams(GridArea roiArea, bool syncDisplay);

  /// 计算当前可测量区域在完整视图中的归一化矩形
  Rect calMeasureAreaInFullVisual(
      double zoomFactor, Offset zoomOffset, bool isSyncDisplay, GridArea area);

  /// 计算当前URM视图在完整视图中的归一化矩形
  Rect calURMScreenInFullVisual(
      double zoomFactor, Offset zoomOffset, bool isSyncDisplay, GridArea area);

  /// 获取归一化矩形
  Rect getNormalizedRect(Rect rectA, Rect rectB) {
    double normalizedX = (rectA.left - rectB.left) / rectB.width;
    double normalizedY = (rectA.top - rectB.top) / rectB.height;
    double normalizedWidth = rectA.width / rectB.width;
    double normalizedHeight = rectA.height / rectB.height;
    return Rect.fromLTWH(
        normalizedX, normalizedY, normalizedWidth, normalizedHeight);
  }

  Offset pointPctInRect(Rect r, Offset p) {
    double xPctOutR = (p.dx - r.left) / r.width;
    double yPctOutR = (p.dy - r.top) / r.height;
    return Offset(xPctOutR, yPctOutR);
  }

  Offset pointPctOutRect(Rect r, Offset p) {
    double xPctInR = p.dx * r.width + r.left;
    double yPctInR = p.dy * r.height + r.top;
    return Offset(xPctInR, yPctInR);
  }

  /// 有效区域占完整图像区域的比例
  Rect get visualRect => Rect.fromLTWH(
      visualInfo.beamsLeftBoundary, 0, visualInfo.beamsRangePercent, 1);

  ///全图坐标转接口入参坐标
  List<UrmPoint> localToView(
      List<Point<double>> points, Rect urmScreenInFullVisual);

  ///获取ROI所在Urm视图的归一化坐标
  Rect getROIPercentRect(GridArea area);

  /// 获取ROI在Urm视图中的归一化路径
  Path calRoiPathInVisual(
      double zoomFactor, Offset zoomOffset, bool isSyncDisplay, GridArea area);
}

class GridArea {
  final int beamStart;
  final int beamEnd;
  final int sampleStart;
  final int sampleEnd;

  GridArea({
    required this.beamStart,
    required this.beamEnd,
    required this.sampleStart,
    required this.sampleEnd,
  }) : assert(beamStart <= beamEnd && sampleStart <= sampleEnd,
            'beamStart <= beamEnd && sampleStart <= sampleEnd,but got beamStart:$beamStart,beamEnd:$beamEnd,sampleStart:$sampleStart,sampleEnd:$sampleEnd');

  // zero 构造
  GridArea.empty()
      : beamStart = 0,
        beamEnd = 0,
        sampleStart = 0,
        sampleEnd = 0;

  // 从 x,y,w,h 构造
  GridArea.fromXYWH({
    required int x,
    required int y,
    required int w,
    required int h,
  })  : beamStart = x,
        beamEnd = x + w,
        sampleStart = y,
        sampleEnd = y + h;

  // 获取宽度
  int get width => beamEnd - beamStart;
  int get height => sampleEnd - sampleStart;
}
