import 'package:flutter/material.dart';
import 'package:flyinsono/lab/color/lab_colors.dart';
import 'package:fis_measure/interfaces/date_types/point.dart';
import 'package:fis_measure/interfaces/process/items/item_metas.dart';
import 'package:fis_measure/process/primitives/ellipse.dart';

import 'package:fis_measure/process/primitives/utils/urm_sharp_copy.dart';
import 'package:fis_measure/utils/canvas.dart';
import 'package:path_drawing/path_drawing.dart';

class RoiCopyPanel extends StatefulWidget {
  const RoiCopyPanel({super.key, required this.type, required this.array});
  final UrmSharpCopyDataType type;
  final List<UrmSharpCopyData> array;

  @override
  State<RoiCopyPanel> createState() => _RoiCopyPanelState();
}

class _RoiCopyPanelState extends State<RoiCopyPanel> {
  static UrmSharpCopyActiveState? _activeState;
  @override
  Widget build(BuildContext context) {
    _activeState = UrmSharpCopyBoard.activeState;
    return _buildBoard(widget.type, widget.array);
  }

  Widget _buildBoard(UrmSharpCopyDataType type, List<UrmSharpCopyData> array) {
    final children = List<Widget>.generate(2, (index) {
      UrmSharpCopyData? data;
      if (array.length > index) {
        data = array[index];
      }
      return SizedBox(
        width: 100,
        height: 100,
        child: _SharpThumbnail(
          data: data,
          isActive: _activeState != null && _activeState!.index == index,
          onClick: () {
            if (data == null) {
              return;
            }
            if (_activeState != null) {
              if (_activeState!.index == index) {
                _activeState = null;
              } else {
                _activeState = UrmSharpCopyActiveState(type, index);
              }
            } else {
              _activeState = UrmSharpCopyActiveState(type, index);
            }
            UrmSharpCopyBoard.switchActiveState(_activeState);
            setState(() {});
            // controller.onUrmSharpCopyCacheChanged(this, type);
          },
        ),
      );
    }).toList();

    children.insert(
      1,
      Container(
        width: 1,
        height: 80,
        color: LabColors.base400,
        margin: EdgeInsets.symmetric(horizontal: 4.0),
      ),
    );

    return Container(
      decoration: BoxDecoration(
        // 左右边框
        border: Border(
          left: BorderSide(
            color: LabColors.base400,
            width: 1,
          ),
          right: BorderSide(
            color: LabColors.base400,
            width: 1,
          ),
        ),
      ),
      padding: EdgeInsets.all(4.0),
      child: Row(
        children: children,
      ),
    );
  }
}

class _SharpThumbnail extends StatelessWidget {
  final UrmSharpCopyData? data;
  final bool isActive;
  final VoidCallback onClick;

  const _SharpThumbnail({
    required this.data,
    required this.isActive,
    required this.onClick,
  });

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, c) {
        if (data == null) {
          return SizedBox();
        }
        return MouseRegion(
          cursor: SystemMouseCursors.click,
          child: GestureDetector(
            onTap: () {
              onClick.call();
            },
            child: Container(
              color: isActive ? LabColors.base600 : null,
              child: CustomPaint(
                painter: ShapeThumbnailPainter(data!),
                size: Size(c.maxWidth, c.maxHeight),
              ),
            ),
          ),
        );
      },
    );
  }
}

class ShapeCopyPainter extends CustomPainter {
  static final ellipseHelper = Ellipse(
    ItemMeta("", measureType: "", description: '', outputs: []),
    null,
  )..isClosed = true;
  // static final ellipseFeatureHelper =
  //     EllipseFeature(ellipseFeatureHelper, DPoint.zero);

  static const dashSpace = 1.0;

  static final paintPan = Paint()
    ..color = Colors.white
    ..isAntiAlias = true
    ..strokeWidth = 2
    ..style = PaintingStyle.stroke;

  final UrmSharpCopyData data;

  final bool isURMDualImages;

  ShapeCopyPainter(
    this.data, {
    this.isURMDualImages = false,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final points = data.points;

    if (data is RectUrmSharpCopyData) {
      _drawRect(canvas, size, points);
    } else if (data is EllipseUrmSharpCopyData) {
      _drawEllipse(canvas, size, points);
    } else {
      _drawTrace(canvas, size, points);
    }
  }

  void _drawRect(Canvas canvas, Size size, List<DPoint> points) {
    final startOffset = points[0].scale2Size(size).toOffset();
    final endOffset = points[1].scale2Size(size).toOffset();
    canvas.drawDashRect(startOffset, endOffset, 1, dashSpace, paintPan);
  }

  void _drawEllipse(
    Canvas canvas,
    Size size,
    List<DPoint> points,
  ) {
    final p = EllipseFeatureForRoiCopy(ellipseHelper, points.first);
    for (var i = 1; i < points.length; i++) {
      p.innerPoints[i] = points[i];
    }
    p.activeIndex = 2;
    p.paintSharpOnly(
      canvas,
      size,
      customPaintPen: paintPan,
    );
    return;
  }

  void _drawTrace(Canvas canvas, Size size, List<DPoint> points) {
    if (points.length > 1) {
      final startPoint = points.first.scale2Size(size).toOffset();
      final Path path = Path();
      path.moveTo(startPoint.dx, startPoint.dy);
      for (var i = 1; i < points.length; i++) {
        final point = points[i].scale2Size(size).toOffset();
        path.lineTo(point.dx, point.dy);
      }
      final isClosed = true;
      if (isClosed) {
        path.lineTo(startPoint.dx, startPoint.dy);
      }
      canvas.drawPath(
        dashPath(path, dashArray: CircularIntervalList([2.0, 10.0])),
        paintPan,
      );
    }
  }

  @override
  bool shouldRepaint(covariant ShapeCopyPainter oldDelegate) {
    return oldDelegate.data != data;
  }
}

class ShapeThumbnailPainter extends CustomPainter {
  static final ellipseHelper = Ellipse(
    ItemMeta("", measureType: "", description: '', outputs: []),
    null,
  )..isClosed = true;

  static const dashSpace = 1.0;

  static final paintPan = Paint()
    ..color = Colors.white
    ..isAntiAlias = true
    ..strokeWidth = 1
    ..style = PaintingStyle.stroke;

  final UrmSharpCopyData data;

  final bool isURMDualImages;

  ShapeThumbnailPainter(
    this.data, {
    this.isURMDualImages = false,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final points = data.points;

    if (data is RectUrmSharpCopyData) {
      _drawRect(canvas, size, points);
    } else if (data is EllipseUrmSharpCopyData) {
      _drawEllipse(canvas, size, points);
    } else {
      _drawTrace(canvas, size, points);
    }
  }

  void _drawRect(Canvas canvas, Size size, List<DPoint> points) {
    final startOffset = points[0].scale2Size(size).toOffset();
    final endOffset = points[1].scale2Size(size).toOffset();
    final rect = Rect.fromPoints(startOffset, endOffset);
    final scaleW = size.width / rect.width;
    final scaleH = size.height / rect.height;
    final scale = scaleW < scaleH ? scaleW : scaleH;
    final Offset center = rect.center;
    final dx = size.width / 2 - center.dx * scale;
    final dy = size.height / 2 - center.dy * scale;
    canvas.translate(dx, dy);
    canvas.scale(scale, scale);
    paintPan.strokeWidth = 1 / scale;
    canvas.drawRect(rect, paintPan);
  }

  void _drawEllipse(
    Canvas canvas,
    Size size,
    List<DPoint> points,
  ) {
    final p = EllipseFeatureForRoiCopy(ellipseHelper, points.first);
    for (var i = 1; i < points.length; i++) {
      p.innerPoints[i] = points[i];
    }
    p.activeIndex = 2;
    p.paintShapeFitInSize(
      canvas,
      size,
      paintPan,
    );
    return;
  }

  void _drawTrace(Canvas canvas, Size size, List<DPoint> points) {
    if (points.length > 1) {
      final startPoint = points.first.scale2Size(size).toOffset();
      final Path path = Path();
      path.moveTo(startPoint.dx, startPoint.dy);
      for (var i = 1; i < points.length; i++) {
        final point = points[i].scale2Size(size).toOffset();
        path.lineTo(point.dx, point.dy);
      }
      final isClosed = true;
      if (isClosed) {
        path.lineTo(startPoint.dx, startPoint.dy);
      }
      // 获取外接矩形，调整画布使其居中，且撑满
      final rect = path.getBounds();
      final scaleW = size.width / rect.width;
      final scaleH = size.height / rect.height;
      final scale = scaleW < scaleH ? scaleW : scaleH;
      final Offset center = rect.center;
      final dx = size.width / 2 - center.dx * scale;
      final dy = size.height / 2 - center.dy * scale;
      canvas.translate(dx, dy);
      canvas.scale(scale, scale);
      paintPan.strokeWidth = 1 / scale;
      canvas.drawPath(
        path,
        paintPan,
      );
    }
  }

  @override
  bool shouldRepaint(covariant ShapeThumbnailPainter oldDelegate) {
    return oldDelegate.data != data;
  }
}
