import 'dart:math';
import 'package:flyinsono/lab/pages/lab_image/urm_data_processor/calculator/sector_shape.dart';
import 'package:flyinsono/lab/pages/lab_image/urm_data_processor/index.dart';
import 'package:flyinsono/lab/pages/lab_image/widgets/image_roi_overlay/controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class RoiCanvasLayer extends GetView<ImageRoiOverlayController> {
  const RoiCanvasLayer({
    Key? key,
    required this.tabHashCode,
  }) : super(key: key);

  @override
  String? get tag => tabHashCode;

  final String tabHashCode;

  @override
  Widget build(BuildContext context) {
    return GetBuilder<ImageRoiOverlayController>(
      tag: tabHashCode,
      id: ImageRoiOverlayController.imageRoiCanavsId,
      builder: (_) {
        return ClipRect(
          child: SizedBox.expand(
            child: RepaintBoundary(
              child: CustomPaint(
                painter: controller.isLinear
                    ? _RoiPainter(
                        controller.roiStartPointRelativeToImage,
                        controller.roiEndPointRelativeToImage,
                        roiViewType: controller.roiViewType,
                      )
                    : _ConvexRoiPainter(
                        controller.roiStartPointRelativeToImage,
                        controller.roiEndPointRelativeToImage,
                        controller.zeroCenterOffset,
                        roiViewType: controller.roiViewType,
                      ),
              ),
            ),
          ),
        );
      },
    );
  }
}

class _RoiPainter extends CustomPainter {
  final Point<double>? startPoint;
  final Point<double>? endPoint;
  final RoiViewType roiViewType;
  _RoiPainter(
    this.startPoint,
    this.endPoint, {
    this.roiViewType = RoiViewType.nomal,
  });

  @override
  void paint(Canvas canvas, Size size) {
    switch (roiViewType) {
      case RoiViewType.nomal:
        paintNomalRoi(canvas, size);
        break;
      case RoiViewType.leftRightHalfHalf:
        paintLeftRightHalfHalfRoi(canvas, size);
        break;
    }
  }

  void paintNomalRoi(Canvas canvas, Size size) {
    if (startPoint == null || endPoint == null) {
      return;
    }
    final Offset a = Offset(
        this.startPoint!.x * size.width, this.startPoint!.y * size.height);
    final Offset b =
        Offset(this.endPoint!.x * size.width, this.endPoint!.y * size.height);
    final paint = Paint()
      ..color = Colors.white
      ..strokeWidth = 2
      ..style = PaintingStyle.stroke;
    canvas.drawRect(
      Rect.fromPoints(a, b),
      paint,
    );
  }

  void paintLeftRightHalfHalfRoi(Canvas canvas, Size size) {
    if (startPoint == null || endPoint == null) {
      return;
    }
    final Offset a = Offset(
        this.startPoint!.x * size.width / 2, this.startPoint!.y * size.height);
    final Offset b = Offset(
        this.endPoint!.x * size.width / 2, this.endPoint!.y * size.height);
    final Offset a2 = Offset(
        this.startPoint!.x * size.width / 2 + size.width / 2,
        this.startPoint!.y * size.height);
    final Offset b2 = Offset(this.endPoint!.x * size.width / 2 + size.width / 2,
        this.endPoint!.y * size.height);
    final paint = Paint()
      ..color = Colors.white
      ..strokeWidth = 2
      ..style = PaintingStyle.stroke;
    canvas.drawRect(
      Rect.fromPoints(a, b),
      paint,
    );
    canvas.drawRect(
      Rect.fromPoints(a2, b2),
      paint,
    );
  }

  @override
  bool shouldRepaint(covariant _RoiPainter oldDelegate) {
    return oldDelegate.hashCode != hashCode;
  }
}

/// 弧阵 ROI Painter

class _ConvexRoiPainter extends CustomPainter {
  final Point<double>? startPoint;
  final Point<double>? endPoint;
  final RoiViewType roiViewType;
  final Offset zeroCenterOffset; // 圆心坐标原点偏移
  _ConvexRoiPainter(
    this.startPoint,
    this.endPoint,
    this.zeroCenterOffset, {
    this.roiViewType = RoiViewType.nomal,
  });

  @override
  void paint(Canvas canvas, Size size) {
    switch (roiViewType) {
      case RoiViewType.nomal:
        paintNomalRoi(canvas, size);
        break;
      case RoiViewType.leftRightHalfHalf:
        paintLeftRightHalfHalfRoi(canvas, size);
        break;
    }
  }

  void paintNomalRoi(Canvas canvas, Size size) {
    if (startPoint == null || endPoint == null) {
      return;
    }
    final Offset a = Offset(
        this.startPoint!.x * size.width, this.startPoint!.y * size.height);
    final Offset b =
        Offset(this.endPoint!.x * size.width, this.endPoint!.y * size.height);
    final paint = Paint()
      ..color = Colors.white
      ..strokeWidth = 2
      ..style = PaintingStyle.stroke;
    canvas.drawRect(
      Rect.fromPoints(a, b),
      paint,
    );
  }

  // 坐标转角度

  void paintLeftRightHalfHalfRoi(Canvas canvas, Size size) {
    if (startPoint == null || endPoint == null) {
      return;
    }
    final Offset a = Offset(
        this.startPoint!.x * size.width / 2, this.startPoint!.y * size.height);
    final Offset b = Offset(
        this.endPoint!.x * size.width / 2, this.endPoint!.y * size.height);
    final leftCenter = Offset(zeroCenterOffset.dx * size.width / 2,
        zeroCenterOffset.dy * size.height);
    final rightCenter = Offset(
        zeroCenterOffset.dx * size.width / 2 + size.width / 2,
        zeroCenterOffset.dy * size.height);
    final paint = Paint()
      ..color = Colors.white
      ..strokeWidth = 2
      ..style = PaintingStyle.stroke;
    // 起始点半径
    final double startRadius =
        sqrt(pow(a.dx - leftCenter.dx, 2) + pow(a.dy - leftCenter.dy, 2));
    // 终点半径
    final double endRadius =
        sqrt(pow(b.dx - leftCenter.dx, 2) + pow(b.dy - leftCenter.dy, 2));
    // 计算起始角
    final startAngle = atan2(a.dy - leftCenter.dy, a.dx - leftCenter.dx);
    // 计算终点角
    final endAngle = atan2(b.dy - leftCenter.dy, b.dx - leftCenter.dx);
    // 计算sweepAngle
    final sweepAngle = endAngle - startAngle;
    SectorShape leftSector = SectorShape(
      center: leftCenter,
      innerRadius: startRadius,
      outRadius: endRadius,
      startAngleRad: startAngle,
      sweepAngleRad: sweepAngle,
    );
    SectorShape rightSector = SectorShape(
      center: rightCenter,
      innerRadius: startRadius,
      outRadius: endRadius,
      startAngleRad: startAngle,
      sweepAngleRad: sweepAngle,
    );
    leftSector.draw(
        canvas, paint, Rect.fromLTWH(0, 0, size.width / 2, size.height));
    rightSector.draw(canvas, paint,
        Rect.fromLTWH(size.width / 2, 0, size.width / 2, size.height));

    // final greenPaint = Paint()
    //   ..color = Colors.green
    //   ..strokeWidth = 2
    //   ..style = PaintingStyle.stroke;
    // rightSector.drawBoundingBox(canvas, greenPaint);
  }

  @override
  bool shouldRepaint(covariant _ConvexRoiPainter oldDelegate) {
    return oldDelegate.hashCode != hashCode;
  }
}
