import 'package:flyinsono/lab/mock_data/mock_rpc.dart';
import 'package:flyinsono/lab/pages/lab_image/urm_data_processor/urm_enums.dart';
import 'package:flyinsono/lab/pages/lab_image/widgets/image_measure_overlay/controller.dart';
import 'package:flyinsono/lab/pages/lab_image/widgets/vid_ui_repaint_overlay/controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'dart:ui' as ui;

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

  @override
  String? get tag => tabHashCode;

  final String tabHashCode;

  @override
  Widget build(BuildContext context) {
    return GetBuilder<VidUIRepaintOverlayController>(
      tag: tabHashCode,
      id: VidUIRepaintOverlayController.vidUIRepaintCanavsId,
      builder: (_) {
        if (!controller.isURMParamLoaded) {
          return Container();
        }
        Widget content;
        if (controller.isSyncDisplay) {
          content = ClipRect(
            child: SizedBox.expand(
              child: RepaintBoundary(
                child: CustomPaint(
                  painter: _VidUIPainter(
                    urmColorBar: controller.urmColorBar,
                    perfusionColorBar: controller.perfusionColorBar,
                    showPerfusionColorBar:
                        controller.minPerfusionFeatureId != null,
                    colorBarOffset: controller.getColorBarOffset(),
                    iconOffset: controller.getIconOffset(),
                    displayTop: controller.displayTop,
                    displayBottom: controller.displayBottom,
                    urmImageType: controller.urmImageType,
                    tissueColorBar: controller.tissueColorBar,
                    timeMotionColorBar: controller.timeMotionColorBar,
                    urmMaxVal: controller.urmMaxVal,
                    urmMinVal: controller.urmMinVal,
                    isLinear: controller.isLinear,
                    vinnoLogoIconImage: controller.vinnoLogoIconImage,
                    currImageType: controller.currImageType,
                    startingFrame: controller.startingFrame,
                    totalFrame: controller.totalFrame,
                    startTime: controller.startTime,
                    endTime: controller.endTime,
                  ),
                ),
              ),
            ),
          );
        } else {
          content = ClipRect(
            child: SizedBox.expand(
              child: RepaintBoundary(
                child: CustomPaint(
                  painter: _URMUIPainter(
                    urmColorBar: controller.urmColorBar,
                    perfusionColorBar: controller.perfusionColorBar,
                    showPerfusionColorBar:
                        controller.minPerfusionFeatureId != null,
                    colorBarOffset: controller.getColorBarOffset(),
                    iconOffset: controller.getIconOffset(),
                    displayTop: controller.displayTop,
                    displayBottom: controller.displayBottom,
                    urmImageType: controller.urmImageType,
                    urmMaxVal: controller.urmMaxVal,
                    urmMinVal: controller.urmMinVal,
                    isLinear: controller.isLinear,
                    vinnoLogoIconImage: controller.vinnoLogoIconImage,
                    currImageType: controller.currImageType,
                    startingFrame: controller.startingFrame,
                    totalFrame: controller.totalFrame,
                    startTime: controller.startTime,
                    endTime: controller.endTime,
                  ),
                ),
              ),
            ),
          );
        }
        return Stack(
          children: [
            content,
            if (controller.currImageType == ImageType.URM_Result) _buildScale(),
          ],
        );
      },
    );
  }

  Widget _buildScale() {
    final currentURMProcessor = controller.urmDataProcessor;
    return Positioned(
      bottom: 10,
      right: currentURMProcessor.visualInfo.isLeftRight ? 270 : 320,
      child: GetBuilder<VidUIRepaintOverlayController>(
        tag: tabHashCode,
        id: VidUIRepaintOverlayController.scaleBarId,
        builder: (_) {
          double imageAreaWidth = ImageMeasureOverlayController.imageAreaWidth;
          if (currentURMProcessor.isSyncDisplay &&
              currentURMProcessor.visualInfo.isLeftRight) {
            imageAreaWidth = imageAreaWidth / 2;
          }
          if (ImageMeasureOverlayController.imageWidth <= 0 ||
              imageAreaWidth <= 0) {
            return SizedBox.shrink();
          }
          double scale = 0.05;
          double imageWidth = ImageMeasureOverlayController.imageWidth;
          if (!currentURMProcessor.isSyncDisplay) {
            var percent = currentURMProcessor.measureAreaInFullVisual.right -
                currentURMProcessor.measureAreaInFullVisual.left;
            imageWidth = imageWidth * percent * currentURMProcessor.zoomFactor;
          }
          double scaleWidth =
              scale * imageWidth / currentURMProcessor.zoomFactor * 10;

          String formattedValue;
          if (scaleWidth < 0.95) {
            double scaleWidthUm = scaleWidth * 1000;
            if (scaleWidthUm > 100) {
              int scaleWidthUmInt = (scaleWidthUm / 100).round() * 100;
              scale = scaleWidthUmInt /
                  1000 /
                  imageWidth *
                  currentURMProcessor.zoomFactor /
                  10;
              formattedValue = (scaleWidthUmInt).toStringAsFixed(2) + " μm";
            } else {
              int scaleWidthUmInt = (scaleWidthUm / 10).round() * 10;
              scale = scaleWidthUmInt /
                  1000 /
                  imageWidth *
                  currentURMProcessor.zoomFactor /
                  10;
              formattedValue = (scaleWidthUmInt).toStringAsFixed(2) + " μm";
            }
          } else {
            // ///这里重新计算比例尺宽度，为了让数值显示整数
            int scaleWidthInt = scaleWidth.round();
            scale = scaleWidthInt /
                imageWidth *
                currentURMProcessor.zoomFactor /
                10;
            formattedValue = scaleWidthInt.toStringAsFixed(2) + " mm";
            //formattedValue = scaleWidth.toStringAsFixed(2) + " mm";
          }
          return IgnorePointer(
            ignoring: true,
            child: Column(
              children: [
                Container(
                  width: imageAreaWidth * scale,
                  height: 4,
                  decoration: new BoxDecoration(
                    border: Border(
                      left: BorderSide(
                        width: 2.0,
                        color: Colors.yellow,
                      ),
                      right: BorderSide(
                        width: 2.0,
                        color: Colors.yellow,
                      ),
                      bottom: BorderSide(
                        width: 2.0,
                        color: Colors.yellow,
                      ),
                    ),
                  ),
                ),
                Text(
                  '$formattedValue',
                  style: TextStyle(
                    color: Colors.yellow,
                  ),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

class _VidUIPainter extends CustomPainter {
  _VidUIPainter({
    required this.urmColorBar,
    required this.perfusionColorBar,
    required this.vinnoLogoIconImage,
    required this.colorBarOffset,
    required this.displayTop,
    required this.displayBottom,
    required this.iconOffset,
    required this.urmImageType,
    required this.tissueColorBar,
    required this.timeMotionColorBar,
    required this.showPerfusionColorBar,
    required this.urmMaxVal,
    required this.urmMinVal,
    required this.isLinear,
    required this.currImageType,
    required this.startingFrame,
    required this.totalFrame,
    required this.startTime,
    required this.endTime,
  });
  final ui.Image? urmColorBar;
  final ui.Image? perfusionColorBar;
  final ui.Image? vinnoLogoIconImage;
  final ui.Image? tissueColorBar;
  final ui.Image? timeMotionColorBar;

  final bool showPerfusionColorBar;

  final double urmMaxVal;
  final double urmMinVal;

  final bool isLinear;
  final int startingFrame;
  final int totalFrame;

  final double startTime;
  final double endTime;

  final Offset colorBarOffset;
  final Offset iconOffset;
  final double displayTop;
  final double displayBottom;
  final UrmImageType urmImageType;

  final ImageType currImageType;
  // colorbar 固定尺寸
  static const double colorBarWidth = 10;
  static const double colorBarHeight = 128;
  // vinno logo 固定尺寸
  static const double logoWidth = 32;
  static const double logoHeight = 26;
  // 灰阶 color bar 顶部距离
  static const double tissueColorBarTopOffset = logoHeight + 4;
  // colorbar 间距
  static const double colorBarSpecing = 20;

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint();

    /// 灰阶
    if (tissueColorBar != null && currImageType == ImageType.URM) {
      Rect grayscaleColorSrc = Rect.fromLTWH(
        0,
        0,
        tissueColorBar!.width.toDouble(),
        tissueColorBar!.height.toDouble(),
      );
      Rect grayscaleColorbarDst = Rect.fromLTWH(
        size.width * (iconOffset.dx - 0.5) + 10,
        tissueColorBarTopOffset,
        colorBarWidth,
        colorBarHeight,
      );

      /// 弧阵特殊处理
      if (!isLinear) {
        grayscaleColorbarDst = Rect.fromLTWH(
          size.width * (iconOffset.dx - 0.5) + 10,
          tissueColorBarTopOffset,
          colorBarWidth,
          colorBarHeight,
        );
      } else {
        grayscaleColorbarDst = Rect.fromLTWH(
          size.width * (iconOffset.dx - 0.5) - 15,
          tissueColorBarTopOffset,
          colorBarWidth,
          colorBarHeight,
        );
      }

      canvas.drawImageRect(
        tissueColorBar!,
        grayscaleColorSrc,
        grayscaleColorbarDst,
        paint,
      );
    }

    /// 灰阶 colorbar
    if (timeMotionColorBar != null && currImageType == ImageType.URM) {
      Rect rightGrayscaleColorBarSrc = Rect.fromLTWH(
        0,
        0,
        timeMotionColorBar!.width.toDouble(),
        timeMotionColorBar!.height.toDouble(),
      );
      Rect rightGrayscaleColorBarDst = Rect.fromLTWH(
        size.width * colorBarOffset.dx + 25,
        tissueColorBarTopOffset,
        colorBarWidth,
        colorBarHeight,
      );
      canvas.drawImageRect(
        timeMotionColorBar!,
        rightGrayscaleColorBarSrc,
        rightGrayscaleColorBarDst,
        paint,
      );
    }

    /// 测量结果图颜色就需要改成灰阶的
    if (currImageType == ImageType.URM_Result) {
      Rect tissueColorBarSrc = Rect.fromLTWH(
        0,
        0,
        tissueColorBar!.width.toDouble(),
        tissueColorBar!.height.toDouble(),
      );
      Rect tissueColorBarDst = Rect.fromLTWH(
        size.width * colorBarOffset.dx + 25,
        tissueColorBarTopOffset,
        colorBarWidth,
        colorBarHeight,
      );
      canvas.drawImageRect(
        tissueColorBar!,
        tissueColorBarSrc,
        tissueColorBarDst,
        paint,
      );
    }

    /// 绘制icon
    Rect vinnoLogoSrc = Rect.fromLTWH(
      0,
      0,
      vinnoLogoIconImage!.width.toDouble(),
      vinnoLogoIconImage!.height.toDouble(),
    );
    Rect vinnoLogoLeftDst = Rect.fromLTWH(
      !isLinear ? logoWidth : size.width * (iconOffset.dx - 0.5) - logoWidth,
      size.height * colorBarOffset.dy,
      logoWidth,
      logoHeight,
    );

    /// 弧阵特殊处理 绘制左侧icon
    Rect vinnoLogoRightDst = Rect.fromLTWH(
      !isLinear
          ? size.width * iconOffset.dx + logoWidth
          : size.width * iconOffset.dx - logoWidth,
      size.height * colorBarOffset.dy,
      logoWidth,
      logoHeight,
    );
    canvas.drawImageRect(
      vinnoLogoIconImage!,
      vinnoLogoSrc,
      vinnoLogoLeftDst,
      paint,
    );
    canvas.drawImageRect(
      vinnoLogoIconImage!,
      vinnoLogoSrc,
      vinnoLogoRightDst,
      paint,
    );

    /// vid 原URM不渲染下面的
    if (currImageType == ImageType.URM) return;
    double urmCurrentTime =
        (startingFrame / totalFrame) * (endTime - startTime) + startTime;

    String urmCurrentTimeStr = _formatSeconds(urmCurrentTime.toInt());

    /// 绘制时间
    final urmCurrentTimeTextPainter = TextPainter(
      text: TextSpan(
        text: urmCurrentTimeStr,
        style: TextStyle(fontSize: 14, color: Colors.yellow),
      ),
      textDirection: TextDirection.ltr,
    );

    urmCurrentTimeTextPainter.layout(); // 计算文本布局
    urmCurrentTimeTextPainter.paint(
      canvas,
      Offset(
        size.width * iconOffset.dx - 45,
        size.height - 30,
      ),
    ); // 在画布上绘制文本

    if (urmColorBar == null) return;
    drawScale(canvas, size, displayTop, displayBottom, colorBarOffset.dx);
    // if (!kDebugMode) {
    //   return;
    // }

    /// 绘制 urmColorbar - 同 视频的colorbar 角度图是一个圆形
    if (urmImageType == UrmImageType.Angle) {
      Rect urmColorbarSrc = Rect.fromLTWH(
        0,
        0,
        urmColorBar!.width.toDouble(),
        urmColorBar!.height.toDouble(),
      );
      Rect urmColorbarDst = Rect.fromLTWH(
        size.width - 30,
        size.height - 30,
        30,
        30,
      );
      canvas.drawImageRect(urmColorBar!, urmColorbarSrc, urmColorbarDst, paint);
    } else {
      Rect urmColorbarSrc = Rect.fromLTWH(
        0,
        0,
        urmColorBar!.width.toDouble(),
        urmColorBar!.height.toDouble(),
      );
      Rect urmColorbarDst = Rect.fromLTWH(
        size.width * colorBarOffset.dx + 25,
        tissueColorBarTopOffset + colorBarSpecing + colorBarHeight,
        colorBarWidth,
        colorBarHeight,
      );
      canvas.drawImageRect(urmColorBar!, urmColorbarSrc, urmColorbarDst, paint);

      final urmMaxValTextPainter = TextPainter(
        textAlign: TextAlign.center,
        text: TextSpan(
          text: urmMaxVal.toStringAsFixed(1),
          style: TextStyle(fontSize: 14, color: Colors.yellow),
        ),
        textDirection: TextDirection.ltr,
      );

      urmMaxValTextPainter.layout(); // 计算文本布局
      urmMaxValTextPainter.paint(
        canvas,
        Offset(
          size.width * colorBarOffset.dx + 30 - urmMaxValTextPainter.width / 2,
          tissueColorBarTopOffset +
              colorBarSpecing +
              colorBarHeight -
              urmMaxValTextPainter.height,
        ),
      ); // 在画布上绘制文本

      final urmMinValTextPainter = TextPainter(
        textAlign: TextAlign.center,
        text: TextSpan(
          text: urmMinVal.toStringAsFixed(1),
          style: TextStyle(fontSize: 14, color: Colors.yellow),
        ),
        textDirection: TextDirection.ltr,
      );

      urmMinValTextPainter.layout(); // 计算文本布局
      urmMinValTextPainter.paint(
        canvas,
        Offset(
          size.width * colorBarOffset.dx + 30 - urmMinValTextPainter.width / 2,
          tissueColorBarTopOffset + colorBarSpecing + colorBarHeight * 2,
        ),
      ); // 在画布上绘制文本
    }

    /// 绘制灌注图
    if (perfusionColorBar != null && showPerfusionColorBar) {
      // 绘制 perfusionColorBar
      Rect src = Rect.fromLTWH(
        0,
        0,
        perfusionColorBar!.width.toDouble(),
        perfusionColorBar!.height.toDouble(),
      );

      Rect dst = Rect.fromLTWH(
        size.width * colorBarOffset.dx + 25,
        tissueColorBarTopOffset + (colorBarSpecing + colorBarHeight) * 2,
        colorBarWidth,
        colorBarHeight,
      );
      canvas.drawImageRect(perfusionColorBar!, src, dst, paint);
    }
  }

  // 比例尺绘制【入参 displaytop(cm),displaybottom(cm)】,在 0.2cm 的整数倍处绘制短横刻度，1 的整数倍时绘制长横刻度并标注数字
  void drawScale(
    Canvas canvas,
    Size size,
    double displayTop,
    double displayBottom,
    double offsetXPct,
  ) {
    final double strokeWidth = 1; // 刻度线厚度
    final int longScaleWidth = 12; // 长刻度宽度
    final int shortScaleWidth = 8; // 短刻度宽度
    double scaleInterval = 0.25; // 0.25cm 小刻度间隔
    double longScaleInterval = 1; // 1cm 大刻度间隔
    if (displayBottom - displayTop > 10) {
      scaleInterval = 1;
      longScaleInterval = 5;
    }
    final double fontSize = 15; // 标注数字字体大小
    final Color paintColor = Colors.yellow;
    final paint = Paint()
      ..color = paintColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth;
    final rightTextPainter = TextPainter(
      textAlign: TextAlign.right,
      textDirection: TextDirection.ltr,
    );
    double pixelsPerCm = size.height / (displayBottom - displayTop);
    double displayBottomInt = displayBottom - displayBottom % scaleInterval;
    rightTextPainter.text = TextSpan(
      text: displayBottom.toStringAsFixed(2).replaceAll('.00', ''),
      style: TextStyle(color: paintColor, fontSize: fontSize),
    );
    rightTextPainter.layout();
    double bottomY = size.height - rightTextPainter.height;
    double startOffsetX = size.width * offsetXPct + 20;
    rightTextPainter.paint(
        canvas,
        Offset(
            startOffsetX - longScaleWidth - rightTextPainter.width, bottomY));
    for (double i = displayBottomInt;
        i >= displayTop - 0.1;
        i -= scaleInterval) {
      double y = ((i - displayTop) * pixelsPerCm);
      double startOffsetY = y - strokeWidth / 2;
      if (isApproximateMultiple(i, longScaleInterval, 0.01)) {
        // 绘制长刻度
        canvas.drawLine(
          Offset(startOffsetX - longScaleWidth, startOffsetY),
          Offset(startOffsetX, startOffsetY),
          paint,
        );
        // 绘制标注数字
        rightTextPainter.text = TextSpan(
          text: i.toStringAsFixed(0),
          style: TextStyle(color: paintColor, fontSize: fontSize),
        );
        rightTextPainter.layout();
        double textOffsetY = y - rightTextPainter.height / 2;
        // 边缘修正
        if (textOffsetY < 0 && textOffsetY > -20) {
          textOffsetY = 0;
        } else if (rightTextPainter.height + textOffsetY > size.height) {
          textOffsetY = size.height - rightTextPainter.height;
        }
        rightTextPainter.paint(
            canvas,
            Offset(startOffsetX - longScaleWidth - rightTextPainter.width,
                textOffsetY));
      } else {
        // 绘制短刻度
        canvas.drawLine(
          Offset(startOffsetX - shortScaleWidth, startOffsetY),
          Offset(startOffsetX, startOffsetY),
          paint,
        );
      }
    }
  }

  bool isApproximateMultiple(double a, double b, double tolerance) {
    double ratio = a / b;
    double nearestInteger = ratio.roundToDouble();
    return (ratio - nearestInteger).abs() < tolerance;
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }

  String _formatSeconds(int seconds) {
    int minutes = seconds ~/ 60; // 使用整数除法计算分钟数
    int remainingSeconds = seconds % 60; // 计算剩余的秒数

    String minutesStr = minutes.toString().padLeft(2, '0'); // 补齐两位数
    String secondsStr = remainingSeconds.toString().padLeft(2, '0'); // 补齐两位数

    return '$minutesStr:$secondsStr';
  }
}

class _URMUIPainter extends CustomPainter {
  _URMUIPainter({
    required this.urmColorBar,
    required this.perfusionColorBar,
    required this.vinnoLogoIconImage,
    required this.colorBarOffset,
    required this.displayTop,
    required this.displayBottom,
    required this.iconOffset,
    required this.urmImageType,
    required this.showPerfusionColorBar,
    required this.urmMaxVal,
    required this.urmMinVal,
    required this.isLinear,
    required this.currImageType,
    required this.startingFrame,
    required this.totalFrame,
    required this.startTime,
    required this.endTime,
  });
  final ui.Image? urmColorBar;
  final ui.Image? perfusionColorBar;
  final ui.Image? vinnoLogoIconImage;

  final bool showPerfusionColorBar;

  final double urmMaxVal;
  final double urmMinVal;

  final bool isLinear;
  final int startingFrame;
  final int totalFrame;

  final double startTime;
  final double endTime;

  final Offset colorBarOffset;
  final Offset iconOffset;
  final double displayTop;
  final double displayBottom;
  final UrmImageType urmImageType;

  final ImageType currImageType;
  // colorbar 固定尺寸
  static const double colorBarWidth = 10;
  static const double colorBarHeight = 128;
  // vinno logo 固定尺寸
  static const double logoWidth = 32;
  static const double logoHeight = 26;
  // 灰阶 color bar 顶部距离
  static const double tissueColorBarTopOffset = logoHeight + 4;
  // colorbar 间距
  static const double colorBarSpecing = 20;

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint();

    /// 绘制icon
    Rect vinnoLogoSrc = Rect.fromLTWH(
      0,
      0,
      vinnoLogoIconImage!.width.toDouble(),
      vinnoLogoIconImage!.height.toDouble(),
    );
    Rect vinnoLogoLeftDst = Rect.fromLTWH(
      !isLinear ? logoWidth : size.width * (iconOffset.dx - 0.5) - logoWidth,
      size.height * colorBarOffset.dy,
      logoWidth,
      logoHeight,
    );
    canvas.drawImageRect(
      vinnoLogoIconImage!,
      vinnoLogoSrc,
      vinnoLogoLeftDst,
      paint,
    );

    /// vid 原URM不渲染下面的
    if (currImageType == ImageType.URM) return;
    double urmCurrentTime =
        (startingFrame / totalFrame) * (endTime - startTime) + startTime;

    String urmCurrentTimeStr = _formatSeconds(urmCurrentTime.toInt());

    /// 绘制时间
    final urmCurrentTimeTextPainter = TextPainter(
      text: TextSpan(
        text: urmCurrentTimeStr,
        style: TextStyle(fontSize: 14, color: Colors.yellow),
      ),
      textDirection: TextDirection.ltr,
    );

    urmCurrentTimeTextPainter.layout(); // 计算文本布局
    urmCurrentTimeTextPainter.paint(
      canvas,
      Offset(
        size.width * iconOffset.dx - 45,
        size.height - 30,
      ),
    ); // 在画布上绘制文本

    if (urmColorBar == null) return;
    drawScale(canvas, size, displayTop, displayBottom, colorBarOffset.dx);
    // if (!kDebugMode) {
    //   return;
    // }

    /// 绘制 urmColorbar - 同 视频的colorbar 角度图是一个圆形
    if (urmImageType == UrmImageType.Angle) {
      Rect urmColorbarSrc = Rect.fromLTWH(
        0,
        0,
        urmColorBar!.width.toDouble(),
        urmColorBar!.height.toDouble(),
      );
      Rect urmColorbarDst = Rect.fromLTWH(
        size.width - 30,
        size.height - 30,
        30,
        30,
      );
      canvas.drawImageRect(urmColorBar!, urmColorbarSrc, urmColorbarDst, paint);
    } else {
      Rect urmColorbarSrc = Rect.fromLTWH(
        0,
        0,
        urmColorBar!.width.toDouble(),
        urmColorBar!.height.toDouble(),
      );
      Rect urmColorbarDst = Rect.fromLTWH(
        size.width * colorBarOffset.dx + 25,
        tissueColorBarTopOffset + colorBarSpecing + colorBarHeight,
        colorBarWidth,
        colorBarHeight,
      );
      canvas.drawImageRect(urmColorBar!, urmColorbarSrc, urmColorbarDst, paint);

      final urmMaxValTextPainter = TextPainter(
        textAlign: TextAlign.center,
        text: TextSpan(
          text: urmMaxVal.toStringAsFixed(1),
          style: TextStyle(fontSize: 14, color: Colors.yellow),
        ),
        textDirection: TextDirection.ltr,
      );

      urmMaxValTextPainter.layout(); // 计算文本布局
      urmMaxValTextPainter.paint(
        canvas,
        Offset(
          size.width * colorBarOffset.dx + 30 - urmMaxValTextPainter.width / 2,
          tissueColorBarTopOffset +
              colorBarSpecing +
              colorBarHeight -
              urmMaxValTextPainter.height,
        ),
      ); // 在画布上绘制文本

      final urmMinValTextPainter = TextPainter(
        textAlign: TextAlign.center,
        text: TextSpan(
          text: urmMinVal.toStringAsFixed(1),
          style: TextStyle(fontSize: 14, color: Colors.yellow),
        ),
        textDirection: TextDirection.ltr,
      );

      urmMinValTextPainter.layout(); // 计算文本布局
      urmMinValTextPainter.paint(
        canvas,
        Offset(
          size.width * colorBarOffset.dx + 30 - urmMinValTextPainter.width / 2,
          tissueColorBarTopOffset + colorBarSpecing + colorBarHeight * 2,
        ),
      ); // 在画布上绘制文本
    }

    /// 绘制灌注图
    if (perfusionColorBar != null && showPerfusionColorBar) {
      // 绘制 perfusionColorBar
      Rect src = Rect.fromLTWH(
        0,
        0,
        perfusionColorBar!.width.toDouble(),
        perfusionColorBar!.height.toDouble(),
      );

      Rect dst = Rect.fromLTWH(
        size.width * colorBarOffset.dx + 25,
        tissueColorBarTopOffset + (colorBarSpecing + colorBarHeight) * 2,
        colorBarWidth,
        colorBarHeight,
      );
      canvas.drawImageRect(perfusionColorBar!, src, dst, paint);
    }
  }

  // 比例尺绘制【入参 displaytop(cm),displaybottom(cm)】,在 0.2cm 的整数倍处绘制短横刻度，1 的整数倍时绘制长横刻度并标注数字
  void drawScale(
    Canvas canvas,
    Size size,
    double displayTop,
    double displayBottom,
    double offsetXPct,
  ) {
    final double strokeWidth = 1; // 刻度线厚度
    final int longScaleWidth = 12; // 长刻度宽度
    final int shortScaleWidth = 8; // 短刻度宽度
    double scaleInterval = 0.25; // 0.25cm 小刻度间隔
    double longScaleInterval = 1; // 1cm 大刻度间隔
    if (displayBottom - displayTop > 10) {
      scaleInterval = 1;
      longScaleInterval = 5;
    }
    final double fontSize = 15; // 标注数字字体大小
    final Color paintColor = Colors.yellow;
    final paint = Paint()
      ..color = paintColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth;
    final rightTextPainter = TextPainter(
      textAlign: TextAlign.right,
      textDirection: TextDirection.ltr,
    );
    double pixelsPerCm = size.height / (displayBottom - displayTop);
    double displayBottomInt = displayBottom - displayBottom % scaleInterval;
    rightTextPainter.text = TextSpan(
      text: displayBottom.toStringAsFixed(2).replaceAll('.00', ''),
      style: TextStyle(color: paintColor, fontSize: fontSize),
    );
    rightTextPainter.layout();
    double bottomY = size.height - rightTextPainter.height;
    double startOffsetX = size.width * offsetXPct + 20;
    rightTextPainter.paint(
        canvas,
        Offset(
            startOffsetX - longScaleWidth - rightTextPainter.width, bottomY));
    for (double i = displayBottomInt;
        i >= displayTop - 0.1;
        i -= scaleInterval) {
      double y = ((i - displayTop) * pixelsPerCm);
      double startOffsetY = y - strokeWidth / 2;
      if (isApproximateMultiple(i, longScaleInterval, 0.01)) {
        // 绘制长刻度
        canvas.drawLine(
          Offset(startOffsetX - longScaleWidth, startOffsetY),
          Offset(startOffsetX, startOffsetY),
          paint,
        );
        // 绘制标注数字
        rightTextPainter.text = TextSpan(
          text: i.toStringAsFixed(0),
          style: TextStyle(color: paintColor, fontSize: fontSize),
        );
        rightTextPainter.layout();
        double textOffsetY = y - rightTextPainter.height / 2;
        // 边缘修正
        if (textOffsetY < 0 && textOffsetY > -20) {
          textOffsetY = 0;
        } else if (rightTextPainter.height + textOffsetY > size.height) {
          textOffsetY = size.height - rightTextPainter.height;
        }
        rightTextPainter.paint(
            canvas,
            Offset(startOffsetX - longScaleWidth - rightTextPainter.width,
                textOffsetY));
      } else {
        // 绘制短刻度
        canvas.drawLine(
          Offset(startOffsetX - shortScaleWidth, startOffsetY),
          Offset(startOffsetX, startOffsetY),
          paint,
        );
      }
    }
  }

  bool isApproximateMultiple(double a, double b, double tolerance) {
    double ratio = a / b;
    double nearestInteger = ratio.roundToDouble();
    return (ratio - nearestInteger).abs() < tolerance;
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }

  String _formatSeconds(int seconds) {
    int minutes = seconds ~/ 60; // 使用整数除法计算分钟数
    int remainingSeconds = seconds % 60; // 计算剩余的秒数

    String minutesStr = minutes.toString().padLeft(2, '0'); // 补齐两位数
    String secondsStr = remainingSeconds.toString().padLeft(2, '0'); // 补齐两位数

    return '$minutesStr:$secondsStr';
  }
}
