import 'dart:async';
import 'dart:math';

import 'package:fis_ui/utils/sizer/sizer.dart';
import 'package:fis_measure/view/player/controller.dart';
import 'package:fis_measure/process/workspace/cross_frame.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/advance_debounce.dart';
import 'package:flyinsono/architecture/utils/ui_image_helper.dart';
import 'package:flyinsono/lab/color/lab_colors.dart';
import 'package:flyinsono/lab/components/lab_dialog.dart';
import 'package:flyinsono/lab/manager/interfaces/project.dart';
import 'package:flyinsono/lab/pages/lab_export/entitys/image_type.dart';
import 'package:flyinsono/lab/pages/lab_image/urm_data_processor/index.dart';
import 'package:flyinsono/lab/pages/lab_image/widgets/image_zoom_preview/controller.dart';
import 'package:flyinsono/lab/pages/lab_image/widgets/urm_child_data_panel/controller.dart';
import 'package:flyinsono/lab/pages/lab_image/widgets/urm_result_overlay/index.dart';
import 'package:flyinsono/lab/pages/lab_image/widgets/vid_ui_repaint_overlay/index.dart';
import 'package:flyinsono/lab/pages/lab_main/controller.dart';
import 'package:flyinsono/managers/interfaces/entities/urm_dialog_result.dart';
import 'package:flyinsono/managers/interfaces/export_data.dart';
import 'package:fis_measure/interfaces/process/workspace/application.dart';
import 'package:fis_measure/interfaces/process/items/item_feature.dart';
import 'package:fis_measure/view/measure/measure_result.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/lab/manager/interfaces/analysis.dart';
import 'package:flyinsono/lab/manager/interfaces/measure.dart';
import 'package:flyinsono/lab/manager/interfaces/task.dart';
import 'package:flyinsono/lab/mixin/tab_hook_mixin.dart';
import 'package:flyinsono/lab/mock_data/mock_rpc.dart';
import 'package:flyinsono/pages/measure/helpers/measureData_helper.dart';
import 'package:intl/intl.dart';
import 'widgets/image_trace/controller.dart';
import 'widgets/mark_overlay/controller.dart';
import 'widgets/vid_repaint_overlay/index.dart';
import 'widgets/widgets.dart';
import 'package:get/get.dart';
import 'index.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_common/index.dart';
import 'package:fis_measure/process/workspace/rpc_bridge.dart';
import 'package:fis_measure/process/workspace/urm/application.dart';
import 'package:fis_measure/process/primitives/utils/urm_sharp_copy.dart';
import 'dart:ui';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_common/event/event_type.dart';
import 'dart:ui' as ui;
import 'package:vid/us/vid_us_image.dart';
import 'package:fis_measure/process/workspace/measure_handler.dart'
    hide MeasureModeSelection;

class LabImageController extends GetxController with TabHookMixin {
  LabImageController({required this.tabHashCode});

  @override
  final int tabHashCode;

  final state = LabImageState();

  final analysisManager = Get.find<IURMFunctionManager>();

  final serverTaskManager = Get.find<IServerTaskManager>();

  final measureManager = Get.find<IMeasureManager>();

  /// 项目接口
  final projectManager = Get.find<IProjectManager>();

  /// 当前测量配置的参数
  MeasureModeSelection? measureModeSelection;

  /// 当前
  LabImageActiveArguments? activeArguments;

  // 整个图像页分为六个主要部分

  /// 1: 左侧图像选择器
  late final ImageDataSourcePanelController imageDataSourcePanelController;

  /// 2: 图像播放器
  late final ImageDataPlayerController imageDataPlayerController;

  /// 3: 播放进度控制器
  late final ProgressPanelController progressController;

  /// 4: 图像操作面板
  late final ImageOperatePanelController imageOperatePanelController;

  /// 5. 图像测量层
  late final ImageMeasureOverlayController imageMeasureOverlayController;

  /// 6. URM 后处理结果绘制层
  late final URMResultOverlayController urmResultOverlayController;

  /// 6. Vid UI 重绘层（包含坐标体系以及colorbar）
  late final VidUIRepaintOverlayController vidUIRepaintOverlayController;

  /// 6. Vid 重绘层
  late final VidRepaintOverlayController vidRepaintOverlayController;

  /// 6. ROI 绘制层
  late final ImageRoiOverlayController imageRoiOverlayController;

  /// 7: URM 数据表格
  late final URMChartPanelController urmChartPanelController;

  /// 8: ZOOM 预览小窗
  late final ImageZoomPreviewController imageZoomPreviewController;

  /// 9: 轨迹描绘层
  late final ImageTraceOverlayController imageTraceOverlayController;

  /// 10.标记拖拽层
  late final MarkOverlayController markOverlayController;

  late final UrmChildDataPanelController urmChildDataPanelController;

  final measureHandler = Get.put(MeasureHandler());

  late VidPlayerController playerController;

  final imageCaptureAreakey = GlobalKey();

  ///当前页面失去UI显示时触发
  final onSleepHandler = FEventHandler<bool>();

  ///导出图像格式
  ExportImageFormat exportImageFormat =
      ExportImageFormat(Store.user.imageType, Store.user.videoType);

  String patientName = "";

  ImagePostProcessTask? postProcessTask;

  /// 选中的图片的id
  String currenrtSelectedImageId = "";

  // 当前的 URM 数据处理器
  URMDataProcessor currentURMProcessor = URMDataProcessor();

  //记录选中的【URM Image Type】的值
  UrmImageType _urmImageType = UrmImageType.Den;

  // 图像选中事件
  Future<void> onImageSelected(VidDataInfo info,
      {bool isSelectLeftList = true}) async {
    currentURMProcessor = URMDataProcessor();
    urmChartPanelController.clearAllCharts();
    urmResultOverlayController.deactive();
    vidRepaintOverlayController.deactive();
    vidUIRepaintOverlayController.removePerfusionColorBar(-1);
    vidUIRepaintOverlayController.deactive();
    imageZoomPreviewController.disableZoom();
    imageOperatePanelController.resetStatus();
    state.imageType = ImageType.URM;
    currenrtSelectedImageId = info.id;
    imageRoiOverlayController.drawRoi(null);
    state.isImageDownloading = true;
    if (info.imageType != ImageType.Video) {
      imageDataPlayerController.changeVid(
        info.vidUrl,
        info.coverUrl,
      );
    }

    urmChartPanelController.setChartEnable(false);
    if (isSelectLeftList) {
      urmChildDataPanelController.selectAnalysis(-1);
      urmChildDataPanelController.imageDataList = [];
    } else {
      imageDataSourcePanelController.isSelectUrmData = true;
    }
    markOverlayController.bodyMark = null;
    if (info.imageType == ImageType.URM) {
      ImagePostProcessTask task = ImagePostProcessTask(
        imageCode: info.id,
        taskType: ImagePostProcessTaskEnum.LoadURMParam,
      );

      addPostProcessTask(task);
      imageOperatePanelController.setAdjustPanel(info.imageType);
      vidUIRepaintOverlayController.setAdjustPanel(info.imageType);
      if (isSelectLeftList) {
        await getResultInfo(info.id);
      }
      currentURMProcessor = URMDataProcessor(imageCode: info.id);
      await currentURMProcessor.loadURMParams(newImageCode: info.id);

      _enableRoi();

      vidUIRepaintOverlayController.active();
      imageRoiOverlayController.setURMDataProcessor(currentURMProcessor);
      imageTraceOverlayController.setURMDataProcessor(currentURMProcessor);
      markOverlayController.setURMDataProcessor(currentURMProcessor);
      imageOperatePanelController.changeOperateMode(OperateMode.adjust);
      imageDataPlayerController.setURMDataProcessor(currentURMProcessor);
    } else if (info.imageType == ImageType.URM_Result) {
      urmResultOverlayController.urmImage = null;
      ImagePostProcessTask task = ImagePostProcessTask(
        imageCode: info.id,
        taskType: ImagePostProcessTaskEnum.DrawURMResult,
      );
      addPostProcessTask(task);
      currentURMProcessor = URMDataProcessor(imageCode: info.id);
      await currentURMProcessor.loadURMParams(newImageCode: info.id);
      imageTraceOverlayController.setURMDataProcessor(currentURMProcessor);
      _enableMeasure();
      urmResultOverlayController.active();
      vidUIRepaintOverlayController.active();
      vidRepaintOverlayController.active();
      urmResultOverlayController.setURMDataProcessor(currentURMProcessor);
      vidUIRepaintOverlayController.setURMDataProcessor(currentURMProcessor);
      vidUIRepaintOverlayController.setAdjustPanel(info.imageType);
      vidRepaintOverlayController.setURMDataProcessor(currentURMProcessor);
      imageZoomPreviewController.setURMDataProcessor(currentURMProcessor);

      imageOperatePanelController.setAdjustPanel(info.imageType,
          probeType: currentURMProcessor.probeType);
      imageOperatePanelController.changeOperateMode(OperateMode.adjust);
    } else if (info.imageType == ImageType.Vid) {
      if (isSelectLeftList) {
        await getResultInfo(info.id);
      }
      _enableMeasure();
      imageOperatePanelController.setAdjustPanel(info.imageType);
      state.url = info.vidUrl;
      // state.isOnlyShowUrmInfo = false;
    } else {
      _enableMeasure();
      imageOperatePanelController.setAdjustPanel(info.imageType);
      state.url = info.vidUrl;
    }
    state.imageType = info.imageType;
  }

  void onLoadedFinished() {
    state.isImageDownloading = false;
  }

  Future<void> getResultInfo(String imageCode) async {
    try {
      state.isOnlyShowUrmInfo = false;
      urmChildDataPanelController.selectAnalysis(-1);
      urmChildDataPanelController.imageDataList = [];

      ///获取urm分析结果
      var result = await projectManager.getUrmRemedicalInfosAsync(imageCode);

      if (result != null) {
        List<ImageModel> imageDataList = [];
        result.forEach(
          (ext) {
            var imageType = Get.find<IURMFunctionManager>().getImageType(ext);
            if (imageType != ImageType.URM && imageType != ImageType.Vid) {
              // find urm result vid
              String vidUrl = ext.imageUrl ?? '';
              if (imageType == ImageType.URM_Result) {
                String? urmResultVid =
                    Get.find<IURMFunctionManager>().findURMResultVid(ext);
                if (urmResultVid != null) {
                  vidUrl = urmResultVid;
                }
              }
              SampleRemedicalFileDataTypeEnum fileDataType = ext.fileDataType;
              imageDataList.add(
                ImageModel(
                  id: ext.businessCode ?? '',
                  createTime: ext.createTime ?? DateTime.now(),
                  description: '',
                  fileTypeName: '',
                  fileDataType: fileDataType,
                  vidDataInfo: VidDataInfo(
                    vidUrl: vidUrl,
                    id: ext.businessCode ?? '',
                    coverUrl: ext.coverImgUrl ?? '',
                    sampleRemedicalFileDataTypeEnum: ext.fileDataType,
                    imageType: imageType,
                  ),
                ),
              );
            }
          },
        );
        urmChildDataPanelController.imageDataList = imageDataList;
        if (imageDataList.length > 0) {
          state.isOnlyShowUrmInfo = true;
        }
      }
    } catch (e) {
      print("getUrmRemedicalInfosAsync err：$e");
    }
  }

  // 图像数据加载完成事件
  void onDataHostLoaded(VidPlayerController playerController) {
    state.isImageDownloading = false;
    // 重置复制框状态
    UrmSharpCopyBoard.switchActiveState(null);

    this.playerController = playerController;
    if (state.imageType == ImageType.URM_Result) {
      imageMeasureOverlayController.buildURMMeasureApplication(
        probe: playerController.probe,
        imageCount: playerController.totalFramesCount,
        url: imageDataPlayerController.dataUrl!,
        dataProcessor: currentURMProcessor,
        imageType: state.imageType,
      );
    } else {
      imageMeasureOverlayController.buildApplication(
        playerController.probe,
        playerController.totalFramesCount,
        url: imageDataPlayerController.dataUrl!,
      );
    }

    if (playerController.totalFramesCount == 1 ||
        state.imageType == ImageType.URM_Result) {
      progressController.setProgressPanelEnable(false);
    } else {
      progressController.setProgressPanelEnable(true);
    }
  }

  void onFirstFrameLoaded(VidUsImage e) {
    imageMeasureOverlayController.applicationLoadFrame(e);
    measureModeSelection =
        imageMeasureOverlayController.getMeasureModeSelection(
      e,
    );
    getMeasureApplicationData();

    /// todo
    _getAnnotationList();

    // 如果是 URM 分析结果，不自动播放，只看首帧
    if (state.imageType == ImageType.URM ||
        state.imageType == ImageType.URM_Result) {
      imageDataPlayerController.changePlayStatus(false);
    }

    /// 如果是普通vid不走加载urm参数的
    if (imageOperatePanelController.currImageType == ImageType.Vid) return;

    /// 获取开始时间和结束时间
    currentURMProcessor.loadVisualParams(e);
    vidUIRepaintOverlayController.setURMDataProcessor(currentURMProcessor);
  }

  /// 图像数据缓冲进度事件
  void onBufferProgressChanged(double progress) {
    progressController.bufferProgress = progress;
  }

  /// 获取测量配置的数据
  void getMeasureApplicationData() async {
    MeasureApplicationDTO? measureApplication =
        await measureManager.getMeasureApplicationAsync(
      measureModeSelection: measureModeSelection!,
    );
    imageOperatePanelController.measureApplicationVersion =
        measureApplication?.version ?? '';

    imageOperatePanelController.applicationModes =
        imageMeasureOverlayController.setApplicationModes(
      playerController.currentFrame,
    );
    imageOperatePanelController.getAvailableModes(
      measureApplication?.availableModes ?? [],
    );

    /// 重置rim测量结果值
    imageMeasureOverlayController.rimMeasureResultList = [];
  }

  // 图像播放进度变化事件
  void onProgressChanged(VidProgressInfo progressInfo) {
    print("任务： 执行图像播放进度变化事件 ${progressInfo.currentFrame}");
    progressController.updateProgress(
      currentFrameIndex: progressInfo.currentFrame,
      totalFrames: progressInfo.totalFrames,
      totalDuration: progressInfo.totalDuration,
    );
    imageMeasureOverlayController
        .applicationLoadFrame(playerController.currentFrame);
    if (imageOperatePanelController.currImageType == ImageType.Vid) return;
    currentURMProcessor.loadVisualParams(playerController.currentFrame);

    currentURMProcessor.setCalculator();
    imageMeasureOverlayController.app?.updateRenderReady.emit(this, null);
    executePostProcessTask();
    // progressController.addKeyFrameMark(progressInfo.currentFrame);
  }

  // 图像播放状态变化事件
  void onPlayStatusChanged(bool isPlaying) {
    progressController.updateStatus(isPlaying);
  }

  // 图像帧尺寸变化事件
  void onFrameSizeChanged(int width, int height) {
    imageMeasureOverlayController.setMeasureLayerSize(width, height);
    urmResultOverlayController.setOverlaySize(width, height);
    vidUIRepaintOverlayController.setOverlaySize(width, height);
    vidRepaintOverlayController.setOverlaySize(width, height);
    imageRoiOverlayController.setOverlaySize(width, height);
    imageTraceOverlayController.setOverlaySize(width, height);
    markOverlayController.setOverlaySize(width, height);
  }

  // 图像播放按钮点击事件
  void onPlayButtonClicked(bool isPlaying) {
    print("onPlayButtonClicked: $isPlaying");
    imageDataPlayerController.changePlayStatus(isPlaying);
  }

  /// 手动微调进度
  bool onFrameChangeEvent(int frame) {
    return imageDataPlayerController.onFrameChangeEvent(frame);
  }

  /// 测量项变化事件
  void onChangeMeasureItem(MeasureItemInfo measureItemInfo) {
    imageMeasureOverlayController.changeMeasureItem(measureItemInfo.itemMeta);
  }

  /// 子测量项变化事件（主动触发）
  void onChildMeasureItemChanged(int index) {
    imageMeasureOverlayController.changeChildMeasureItem(index);
  }

  /// 子测量项变化事件（被动触发）
  void onWorkingChildChanged(int index) {
    imageOperatePanelController.selectedChildMeasureItemIndex = index;
  }

  /// 测量项变化完毕事件(触发 ROI 拷贝组件的状态更新)
  void onMeasureItemChanged(bool success) {
    imageOperatePanelController.updateShapeCopyPanel();
  }

  // 完成一次测量后(触发 ROI 拷贝组件的状态更新)
  void onMeasureFinishedOnce(bool success) {
    imageOperatePanelController.updateShapeCopyPanel();
  }

  /// 灌注图创建事件（参数 int 为创建灌注图的测量项 id）
  void onUpdatePerfusion(int featureId) {
    vidUIRepaintOverlayController.createPerfusionColorBar(featureId);
  }

  /// 关键帧变化事件
  void onCrossFramesChanged(List<int> arr) {
    if (arr.isEmpty) {
      progressController.clearKeyFrameMark();
    } else {
      progressController.setKeyFrameMark(arr);
    }
  }

  // 跨帧测量触发事件
  void onCrossFramesTriggered(_) {
    imageMeasureOverlayController.crossImageBaseIndex =
        imageDataSourcePanelController.selectedImageIndex;
  }

  // 跨帧测量结束事件
  void onCrossFramesOver(CrossFrameContext crossFrameContext) {
    final index = imageMeasureOverlayController.crossImageBaseIndex;
    if (index != null &&
        index != imageDataSourcePanelController.selectedImageIndex) {
      imageDataSourcePanelController.selectImage(index);
      imageDataSourcePanelController.scrollToImage(index);
      imageMeasureOverlayController.crossImageBaseIndex = null;
      Future.delayed(const Duration(milliseconds: 500), () {
        imageDataPlayerController
            .onFrameChangeEvent(crossFrameContext.originIndex);
      });
    } else {
      imageDataPlayerController
          .onFrameChangeEvent(crossFrameContext.originIndex);
    }
  }

  // URM 表格更新事件
  void onUpdateChart(URMChartParams params) {
    urmChartPanelController.setChartEnable(true);
    urmChartPanelController.addChart(
      params.featureId,
      params.outerExterPoints,
      params.line,
      params.maxPointIndex,
      params.minPointIndex,
    );
    // 下一帧
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      _onWindowResize(null);
    });
  }

  void onUpdateRimResult(URMRimMesureResult? rimResult) {
    imageMeasureOverlayController.updateRimResult(rimResult);
  }

  /// 图像幅区域变化事件
  void onVisualAreaChanged(String visualArea) {
    imageOperatePanelController.changeMeasureItemCategoryByModeName(visualArea);
  }

  // 操作面板事件处理
  void operatePanelHandler(OperationCall operation) {
    switch (operation.type) {
      case OperationType.SWITCH_URM_IMAGE_TYPE:
        if (operation.arguments is UrmImageType) {
          _urmImageType = operation.arguments;
          handleSwitchUrmImageType(operation.arguments);
        }
        break;
      case OperationType.SWITCH_SYNC_DISPLAY:
        if (operation.arguments is bool) {
          handleSwitchSyncDisplay(operation.arguments);
          vidUIRepaintOverlayController.repaintScale();
        }
        break;
      case OperationType.VIDEO_PLAY:
        if (operation.arguments is bool) {
          handleVideoPlay(operation.arguments as bool);
        }
        break;
      case OperationType.VIDEO_SAVE:
        saveCurrentImageVideo();
        break;
      case OperationType.TRACE:
        print('轨迹绘制已开启');
        _enableTrace();
        break;
      case OperationType.Revert:
        imageTraceOverlayController.clearPoints();
        urmResultOverlayController.updateURMResult();
        vidUIRepaintOverlayController.repaintColorBar();
        break;
      case OperationType.ADJUST_PARAMETER:
        if (operation.arguments is URMParamAdjust) {
          // 拦截 zoom 信号（zoom之前）
          if (operation.arguments.type == URMParamType.ZOOM) {
            Offset zoomCenter = imageZoomPreviewController
                .setScaleParam(operation.arguments.value);
            currentURMProcessor.handleZoomCenterChange(zoomCenter);

            /// 更新测量层
            imageMeasureOverlayController
                .update([ImageMeasureOverlayController.imageMeasureOverlayId]);
          }
          currentURMProcessor.handleParamChange(
            operation.arguments,
          );
          urmResultOverlayController.updateURMResult();

          vidUIRepaintOverlayController.repaintColorBar(
            currentURMProcessor.isVideoMode,
          );

          // ZOOM 之后的行为
          if (operation.arguments.type == URMParamType.ZOOM) {
            vidUIRepaintOverlayController.repaintScale();
            vidRepaintOverlayController.repaintZoomedVid();
          }
        }
        break;
      case OperationType.UNDO_MEASURE:
        int removeId = imageMeasureOverlayController.undoMeasure() + 1;
        urmChartPanelController.removeChart(removeId);
        vidUIRepaintOverlayController.removePerfusionColorBar(removeId);
        // 下一帧
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          _onWindowResize(null);
        });
        break;
      case OperationType.CLEAR_MEASURE:
        imageMeasureOverlayController.clearMeasure();
        urmChartPanelController.clearAllCharts();
        vidUIRepaintOverlayController.removePerfusionColorBar(-1);
        // 下一帧
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          _onWindowResize(null);
        });
        break;
      default:
        break;
    }
  }

  void magnifierChanged(bool value) {
    state.disableMagnifier = value;
  }

  // 查看原始数据
  void viewOriginalImage() {
    if (imageDataSourcePanelController.selectedImageType == ImageType.URM) {
      urmChildDataPanelController.selectAnalysis(-1);
      return;
    }
    var imageData = imageDataSourcePanelController
        .imageDataList[imageDataSourcePanelController.selectedImageIndex];
    var index = imageDataSourcePanelController.imageDataList
        .indexWhere((element) => element.id == imageData.urmOriginalCode);
    imageDataSourcePanelController.selectImage(index);
  }

  // 切换 URM 图像类型
  void handleSwitchUrmImageType(UrmImageType type) {
    imageOperatePanelController.setOptionsByUrmImageType(type);
    imageOperatePanelController
        .buildMeasureItemCategories(imageOperatePanelController.currImageType);

    currentURMProcessor.handleParamChange(
      URMParamAdjust(
        type: URMParamType.UrmImageType,
        value: type,
      ),
    );
    urmResultOverlayController.updateURMResult();
    vidUIRepaintOverlayController.repaintColorBar();
  }

  // 切换同步显示
  Future<void> handleSwitchSyncDisplay(bool syncDisplay) async {
    imageOperatePanelController.setOptionsByURMBlend(syncDisplay);
    urmChartPanelController.setChartEnable(false);
    currentURMProcessor.handleParamChange(
      URMParamAdjust(
        type: URMParamType.SyncDisplay,
        value: syncDisplay,
      ),
    );
    await urmResultOverlayController.updateURMResult();
    vidUIRepaintOverlayController.repaintColorBar();
    imageZoomPreviewController.refreshPreviewStatus(
        syncDisplay: syncDisplay, updateURMImage: true);

    /// 更新测量层
    imageMeasureOverlayController
        .update([ImageMeasureOverlayController.imageMeasureOverlayId]);
  }

  /// 保存图片
  void capturePng() async {
    bool isCaptureState = false; // 是否是截图状态

    if (!isCaptureState) {
      // setState(() {
      //   isCaptureState = true;
      // });
      final application = Get.find<IApplication>();
      List<String> measureModeNameList = [];
      final features = <IMeasureItemFeature>[];
      for (var item in application.measureItems) {
        if (item.measuredFeatures.isNotEmpty) {
          features.addAll(item.measuredFeatures);
        }
        if (item.feature != null) {
          features.add(item.feature!);
        }
      }
      for (var i in features) {
        measureModeNameList.add(i.measureModeName);
      }
      String measureModeNameListString =
          measureModeNameList.toSet().toList().join(';');

      MeasureResult measureResult = MeasureResult(
        measureApplicationName: application.applicationName,
        features: features,
      );
      print(measureModeNameListString);
      await Future.delayed(const Duration(milliseconds: 10), () async {
        final RenderRepaintBoundary? boundary =
            imageCaptureAreakey.currentContext?.findRenderObject()
                as RenderRepaintBoundary?;

        if (boundary != null) {
          final image = await boundary.toImage();
          final byteData = await image.toByteData(format: ImageByteFormat.png);
          final pngBytes = byteData!.buffer.asUint8List();

          bool? result = await MeasureDataHelper.saveImage.call(
            pngBytes,
            '',
            imageDataSourcePanelController.recordId,
            currenrtSelectedImageId,
            measureResult.toDisplay(),
            VidImageSource.Laboratory,
            measureModeNameListString,
          );
          if (result != null && result) {
            PromptBox.toast('保存成功');
            Future.delayed(
              const Duration(
                milliseconds: 800,
              ),
              () {},
            );
            updateRecordImage();
          }

          // setState(() {
          //   isCaptureState = false;
          // });
        }
      });
    }
  }

  /// 缩放中心变更事件
  void onZoomCenterChanged(Offset zoomCenter) {
    currentURMProcessor.handleZoomCenterChange(zoomCenter);
    urmResultOverlayController.updateURMResult();

    vidUIRepaintOverlayController.repaintScale();
    vidRepaintOverlayController.repaintZoomedVid();

    /// 更新测量层
    imageMeasureOverlayController
        .update([ImageMeasureOverlayController.imageMeasureOverlayId]);
  }

  // 工具栏方法处理
  void methodCallHandler(MethodCall methodCall) {
    // TODO 新建一个任务中心，用于处理各种任务
    switch (methodCall.type) {
      case MethodType.URM_ANALYSIS:
        handleURMAnalysis();
        break;
      case MethodType.SAVE_MEASURE_RESULT:
        handleSaveMeasureResult();
        break;
      case MethodType.URM_ANALYSIS_SAVE_VIDEO:
        saveAnalysisVideo();
        break;
      case MethodType.EXPORT_IMAGE:
        exportCurrentImage();
        break;
      case MethodType.FRAMES_UPDATE:
        if (methodCall.arguments is List<int>) {
          var result = methodCall.arguments as List<int>;
          currentURMProcessor.customizedStartFrame = result.first;
          currentURMProcessor.customizedEndFrame = result.last;
        }
        break;
      default:
        break;
    }
  }

  // 执行 URM 分析
  void handleURMAnalysis() async {
    String? imageCode = currenrtSelectedImageId;
    if (imageCode.isNullOrEmpty) {
      return;
    }
    RoiResult? roi = imageRoiOverlayController.getRoiResult();
    if (roi == null) {
      PromptBox.toast('请先框选 ROI');
      return;
    }
    imageRoiOverlayController.drawRoi(null);
    print(
        "ROI:  ${roi.startX}, ${roi.startY}, ${roi.width}, ${roi.height} ${roi.roiXPct} ${roi.roiYPct} ${roi.roiWPct} ${roi.roiHPct} Frame: ${currentURMProcessor.framesGot}");
    // return;
    print("customizedStartFrame: ${currentURMProcessor.customizedStartFrame}");
    print("customizedEndFrame: ${currentURMProcessor.customizedEndFrame}");

    ///执行图像分析
    var batchAnalysisResult = await analysisManager.batchAnalysis(
      analysisList: [
        AnalysisItem(
          x: roi.startX.toDouble(),
          y: roi.startY.toDouble(),
          width: roi.width.toDouble(),
          height: roi.height.toDouble(),
          remedicalCode: imageCode,
          roiXPercent: roi.roiXPct,
          roiYPercent: roi.roiYPct,
          roiWPercent: roi.roiWPct,
          roiHPercent: roi.roiHPct,
          customizedStartFrame:
              max(1, currentURMProcessor.customizedStartFrame),
          customizedEndFrame: currentURMProcessor.customizedEndFrame,
        ),
      ],
      businessCode: tabHashCode.toString(),
    );
    print("batchAnalysisResult: $batchAnalysisResult");
    if (batchAnalysisResult.isNullOrEmpty) {
      PromptBox.toast("分析失败");
    } else {
      dynamic result = await Get.dialog(
        LabDialog(
          title: "URM 分析",
          content: "正在分析",
          confirmText: "转入后台分析",
          confirmLabWidth: 120,
          maxWidth: 400,
          showLoading: true,
          showCloseIcon: false,
          showCancelButton: false,
          mainTaskCode: batchAnalysisResult,
        ),
        barrierDismissible: false,
        barrierColor: LabColors.base100.withOpacity(0.1),
      );
      if (result is bool && result) {
        PromptBox.toast('已转入后台分析，可在任务列表中查看详情');
      } else if (result is UrmDialogResult &&
          result == UrmDialogResult.Complate) {
        PromptBox.toast('分析已完成');
        await getResultInfo(imageCode);
        Future.delayed(Duration(milliseconds: 200), () {
          update([UrmChildDataPanelController.urmAnalysisPanelId]);
        });
      } else if (result is UrmDialogResult &&
          result == UrmDialogResult.AnalysisFailed) {
        PromptBox.toast('分析失败');
      }
    }
  }

  /// 保存分析结果的
  void saveAnalysisVideo() async {
    String? imageCode = currenrtSelectedImageId;
    if (imageCode.isNullOrEmpty) {
      return;
    }
  }

  /// 更新检查图片列表
  Future<void> updateRecordImage() async {
    if (activeArguments != null) {
      List<RecordModel> result = await projectManager.getRecordDetail(
        patientCode: activeArguments!.patient.code,
        patientType:
            activeArguments!.patientType ?? OrganizationPatientTypeEnum.Person,
        selectedPatient: activeArguments!.patient,
      );
      for (RecordModel record in result) {
        if (record.id == activeArguments!.record.id) {
          ImageModel? currentImage = record.images.firstWhereOrNull(
              (element) => element.id == currenrtSelectedImageId);
          if (currentImage == null) return;

          /// Urm的图片
          if (currentImage.vidDataInfo.imageType == ImageType.URM_Result) {
            var index = urmChildDataPanelController.selectedImageIndex;
            await getResultInfo(currentImage.urmOriginalCode ?? '');
            urmChildDataPanelController.selectedImageIndex = index;
            urmChildDataPanelController.updateImageList();
          } else {
            await getResultInfo(currentImage.id);
            urmChildDataPanelController.updateImageList();
            imageDataSourcePanelController.updateImageDataSourcePanel(
              activeArguments!.patient,
              activeArguments!.record,
              record.images,
              imageDataSourcePanelController.selectedImageIndex,
            );
            imageDataSourcePanelController.joinPage();
            imageOperatePanelController.switchMagnifierState(false);
          }
          _setBottomPatientText(name: activeArguments!.patient.name);
        }
      }
    }
  }

  /// 更新底部显示的病人名
  void _setBottomPatientText({String? name}) {
    if (state.noImage) {
      return;
    }
    if (name != null) {
      patientName = name;
    }
    LabMainHook.setBottomCustomText("当前样本：" + patientName);
  }

  // 执行保存测量结果
  void handleSaveMeasureResult() {
    capturePng();
    print("handleSaveMeasureResult");
  }

  /// 启用测量
  void _enableMeasure() {
    imageMeasureOverlayController.active();
    imageRoiOverlayController.deactive();
    imageTraceOverlayController.deactive();
    imageMeasureOverlayController.isAnnotation = false;
  }

  /// 启用注释
  void _enableAnnotation() {
    imageMeasureOverlayController.active();
    imageRoiOverlayController.deactive();
    imageTraceOverlayController.deactive();
    imageMeasureOverlayController.isAnnotation = true;
  }

  /// 启用 ROI
  void _enableRoi() {
    imageMeasureOverlayController.deactive();
    imageTraceOverlayController.deactive();
    imageRoiOverlayController.active();
  }

  ///启用轨迹描绘
  void _enableTrace() {
    imageMeasureOverlayController.deactive();
    imageRoiOverlayController.deactive();
    imageTraceOverlayController.active();
  }

  /// 窗口大小变化事件
  void _onWindowResize(_) {
    urmResultOverlayController.onRenderSizeChanged();
    imageRoiOverlayController.onRenderSizeChanged();
    imageMeasureOverlayController.updateApplicationDisplaySize();
  }

  /// 设置图像后处理任务
  void addPostProcessTask(ImagePostProcessTask task) {
    clearPostProcessTask();
    print("创建任务 ：重建 OperatePanel");
    postProcessTask = task;
  }

  /// 清空图像后处理任务
  void clearPostProcessTask() {
    print("清理后处理任务");
    postProcessTask = null;
  }

  /// 执行图像后处理任务
  void executePostProcessTask() async {
    print("触发后处理任务, 当前选中的图片 图片code:" + currenrtSelectedImageId);
    if (postProcessTask != null &&
        postProcessTask!.imageCode == currenrtSelectedImageId) {
      print("执行后处理任务");
      final cacheTask = postProcessTask;
      postProcessTask = null;
      switch (cacheTask!.taskType) {
        case ImagePostProcessTaskEnum.DrawURMResult:
          await urmResultOverlayController.updateURMResult();
          vidUIRepaintOverlayController.repaintColorBar();
          vidUIRepaintOverlayController.updatePhysicalScale();
          Rect visualRect = currentURMProcessor.getVisualRect();
          imageZoomPreviewController.setBackgroundImageByRect(visualRect);
          break;
        case ImagePostProcessTaskEnum.LoadURMParam:
          print("执行后处理任务:加载 URM 参数 然后重建 OperatePanel 仅在 URM 原始数据触发");
          await currentURMProcessor.loadURMParams(
            newImageCode: cacheTask.imageCode,
          );
          imageOperatePanelController.setFrameData(
            currentURMProcessor.customizedStartFrame,
            currentURMProcessor.customizedEndFrame,
            progressController.totalFrames,
          );
          break;
        default:
          return;
      }
    } else {
      print("未执行后处理任务:后处理任务为空或者图片ID不匹配");
    }
  }

  @override
  void onActive(arguments) {
    print("onActive $arguments");
    if (arguments is LabImageActiveArguments) {
      if (arguments.images.isNotEmpty) {
        state.noImage = false;
      } else {
        state.noImage = true;
        return;
      }
      activeArguments = arguments;
      // TODO 此处切换前需要有一个弹窗询问，如果有未保存的数据，是否保存并切换到新病人/新图像

      imageDataSourcePanelController.updateImageList(
        arguments.patient,
        arguments.record,
        arguments.images,
        arguments.selectedImageIndex,
      );
      imageDataSourcePanelController.joinPage();
      imageOperatePanelController.switchMagnifierState(false);
      _setBottomPatientText(name: arguments.patient.name);
    } else {
      _setBottomPatientText();
    }
  }

  @override
  void onSleep() {
    print("onSleep");
    onSleepHandler.emit(this, true);
    LabMainHook.setBottomCustomText("");
  }

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    super.onInit();
    Sizer.ins.addListener(_onWindowResize);
    imageRoiOverlayController = ImageRoiOverlayController();
    vidUIRepaintOverlayController = VidUIRepaintOverlayController();
    vidRepaintOverlayController = VidRepaintOverlayController();
    imageTraceOverlayController = ImageTraceOverlayController(
      onTraceSelected: onTraceSelected,
    );
    markOverlayController = MarkOverlayController();
    urmResultOverlayController = URMResultOverlayController();
    imageMeasureOverlayController = ImageMeasureOverlayController(
      onWorkingChildChanged: onWorkingChildChanged,
      onCrossFramesChanged: onCrossFramesChanged,
      onCrossFramesTriggered: onCrossFramesTriggered,
      onCrossFramesOver: onCrossFramesOver,
      onUpdateChart: onUpdateChart,
      onUpdateRimResult: onUpdateRimResult,
      onUpdatePerfusion: onUpdatePerfusion,
      onVisualAreaChanged: onVisualAreaChanged,
      onMeasureItemChanged: onMeasureItemChanged,
      onMeasureFinishedOnce: onMeasureFinishedOnce,
    );
    progressController = ProgressPanelController(
      onPlayButtonClicked: onPlayButtonClicked,
      onFrameChangeEvent: onFrameChangeEvent,
    );
    imageOperatePanelController = ImageOperatePanelController(
      onChangeMeasureItem: onChangeMeasureItem,
      onChildMeasureItemChanged: onChildMeasureItemChanged,
      onMethodCall: methodCallHandler,
      onOperationCall: operatePanelHandler,
      onViewOriginalImage: viewOriginalImage,
      onMagnifierChanged: magnifierChanged,
      onOperateModeChange: onOperateModeChange,
      onBodyMarkSelected: onBodyMarkSelected,
    );
    imageDataPlayerController = ImageDataPlayerController(
      onProgressChanged: onProgressChanged,
      onPlayStatusChanged: onPlayStatusChanged,
      onFrameSizeChanged: onFrameSizeChanged,
      onDataHostLoaded: onDataHostLoaded,
      onFirstFrameLoaded: onFirstFrameLoaded,
      onBufferProgressChanged: onBufferProgressChanged,
    );
    imageDataSourcePanelController = ImageDataSourcePanelController(
      onImageSelected: onImageSelected,
      onFirstJoinSelectItem: onFirstJoinSelectItem,
      onRefersh: onRefershDataSource,
    );
    urmChartPanelController = URMChartPanelController();
    urmChildDataPanelController = UrmChildDataPanelController(
      onAnalysisSelect: (value) {
        onImageSelected(value, isSelectLeftList: false);
      },
    );
    imageZoomPreviewController = ImageZoomPreviewController(
      imageCaptureAreakey: imageDataPlayerController.playerKey,
      onZoomCenterChanged: onZoomCenterChanged,
    );
  }

  Future<void> onFirstJoinSelectItem(ImageModel info) async {
    try {
      await getResultInfo(info.urmOriginalCode ?? "");
      var index = urmChildDataPanelController.imageDataList
          .indexWhere((element) => element.id == info.vidDataInfo.id);
      urmChildDataPanelController.selectAnalysis(index);
    } catch (e) {
      print("getUrmRemedicalInfosAsync err：$e");
    }
  }

  /// 注释获取
  void _getAnnotationList() async {
    List<String> annotationList = [];
    final application = Get.find<IApplication>();
    var measureCommentItemResult =
        await measureManager.getCommentsByApplicationAsync(
      application.applicationName,
      application.categoryName,
    );
    imageMeasureOverlayController
            .measureDataController?.measureCommentItemResult =
        measureCommentItemResult?.commentItems ?? [];
    measureCommentItemResult?.commentItems?.forEach((element) {
      annotationList.add(element.text ?? '');
    });
    imageMeasureOverlayController.measureDataController?.annotationList =
        annotationList;
    measureHandler.onAnnotationsLoaded();
  }

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    super.onReady();
  }

  /// 在 [onDelete] 方法之前调用。
  @override
  void onClose() {
    super.onClose();
    Sizer.ins.removeListener(_onWindowResize);
  }

  /// dispose 释放内存
  @override
  void dispose() {
    super.dispose();
    Sizer.ins.removeListener(_onWindowResize);
    imageDataPlayerController.dispose();
    progressController.dispose();
    imageOperatePanelController.dispose();
    imageDataSourcePanelController.dispose();
    urmChartPanelController.dispose();
  }

  Future<void> exportCurrentImage() async {
    var exportManager = Get.find<IExportDataManager>();
    String? imageCode = currenrtSelectedImageId;
    if (imageCode.isNullOrEmpty) {
      return;
    }
    String projectCode = activeArguments?.projectCode ?? '';
    String patientCode = activeArguments?.patient.code ?? '';
    ProjectSampleDataExportResult sampleDatas = await exportManager
        .getProjectSampleDataExport(projectCode, [patientCode]);
    var sampleDetailList = sampleDatas.sampleDetailList ?? [];
    if (sampleDetailList.isEmpty) {
      return;
    }
    SampleDetailInfo sampleDetailInfo = sampleDetailList.first;
    List<SampleRemedicalBasicInfo> sampleRemedicalBasicList =
        sampleDetailInfo.sampleRemedicalBasicList ?? [];
    SampleRemedicalBasicInfo? sampleImageInfo =
        sampleRemedicalBasicList.firstWhereOrNull((element) =>
            element.sampleRemedicalInfoList
                ?.any((element) => element.businessCode == imageCode) ??
            false);
    if (sampleImageInfo == null) {
      return;
    }
    List<SampleRemedicalInfoDTO> sampleRemedicalInfoList =
        sampleImageInfo.sampleRemedicalInfoList!;
    SampleRemedicalInfoDTO imageInfo = sampleRemedicalInfoList
        .firstWhere((element) => element.businessCode == imageCode);
    sampleImageInfo.sampleRemedicalInfoList = [imageInfo];
    sampleDetailInfo.sampleRemedicalBasicList = [sampleImageInfo];
    sampleDatas.sampleDetailList = [sampleDetailInfo];
    String name = sampleDatas.name ?? '';
    String formattedDate =
        DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now());
    name += "数据导出_" + formattedDate;
    if (FPlatform.isWindows) {
      Store.app.setBusy("导出中");
    }
    String taskId = await exportManager.exportDatas(name, '',
        exportImageFormat: exportImageFormat,
        businessCode: projectCode,
        sampleDataInfo: sampleDatas);
    if (taskId.isEmpty) {
      Store.app.cancelBusy();
    }
    int times = 0;
    Timer.periodic(Duration(milliseconds: 500), (timer) {
      try {
        var taskList = exportManager.getLocalTasks(taskId);
        if (taskList.isEmpty) {
          timer.cancel();
          Store.app.cancelBusy();
        } else if (taskList.any((element) => element.rate == 100)) {
          timer.cancel();
          Store.app.cancelBusy();
          PromptBox.toast('导出成功');
        } else if (times > 120) {
          PromptBox.toast('导出失败');
          timer.cancel();
          Store.app.cancelBusy();
        }
      } catch (e) {
        logger.e('exportCurrentImage ex:', e);
        timer.cancel();
        Store.app.cancelBusy();
      }
      times++;
    });
  }

  ///处理视频播放开关逻辑
  void handleVideoPlay(bool isOpen) async {
    if (isOpen) {
      await currentURMProcessor.preLoadURMVideoProcessAsync();
      handleSwitchUrmImageType(UrmImageType.Video);
    } else {
      handleSwitchUrmImageType(_urmImageType);
    }
    update([URMResultOverlayController.imagePlayProgressId]);
  }

  ///保存视频（后处理）
  Future<void> saveCurrentImageVideo() async {
    advanceDebounce(() async {
      Store.app.busy = true;
      try {
        ui.Image? backgroundImage;
        String? base64;
        int? width;
        int? height;
        if (currentURMProcessor.isSyncDisplay) {
          if (currentURMProcessor.zoomOn) {
            backgroundImage = vidRepaintOverlayController.vidImage;
          } else {
            backgroundImage = imageZoomPreviewController.backgroundImage;
          }
          base64 = await ImageHepler.imageToBase64(backgroundImage);
          width = backgroundImage?.width;
          height = backgroundImage?.height;
        }
        String taskCode = await currentURMProcessor.saveAnalysisVideoByTask(
          base64,
          width?.toDouble(),
          height?.toDouble(),
        );
        Store.app.busy = false;
        dynamic result = await Get.dialog(
          LabDialog(
            title: "保存视频",
            content: "正在生成视频",
            confirmText: "转入后台生成",
            confirmLabWidth: 120,
            maxWidth: 400,
            showLoading: true,
            showCloseIcon: false,
            showCancelButton: false,
            mainTaskCode: taskCode,
          ),
          barrierDismissible: false,
          barrierColor: LabColors.base100.withOpacity(0.1),
        );
        if (result is bool && result) {
          PromptBox.toast('已转入后台生成，可在任务列表中查看详情');
        } else if (result is UrmDialogResult &&
            result == UrmDialogResult.Complate) {
          urmChildDataPanelController
              .selectAnalysis(urmChildDataPanelController.selectedImageIndex);
          PromptBox.toast('视频生成完成');
        } else if (result is UrmDialogResult &&
            result == UrmDialogResult.AnalysisFailed) {
          PromptBox.toast('生成失败！');
        }
      } catch (e) {
        Store.app.busy = false;
        return;
      }
    }, "saveCurrentImageVideo");
  }

  void onTraceSelected() {
    urmResultOverlayController.updateURMResult();
    vidUIRepaintOverlayController.repaintColorBar();
  }

  void onOperateModeChange(OperateMode value) {
    if (value == OperateMode.measure) {
      _enableMeasure();
      if (state.imageType == ImageType.URM_Result) {
        // 预加载 URM 测量
        currentURMProcessor.preLoadMeasureFunction();
      }
    } else if (value == OperateMode.annotation) {
      _enableAnnotation();
    }
  }

  void onBodyMarkSelected(String value) {
    markOverlayController.setBodyMark(value);
  }

  void onRefershDataSource(value) {
    updateRecordImage()
        .then((value) => imageDataSourcePanelController.joinPage());
  }
}

class LabImageActiveArguments {
  final PatientModel patient;
  final String? projectCode;
  final RecordModel record;
  final List<ImageModel> images;
  final int? selectedImageIndex;
  final OrganizationPatientTypeEnum? patientType;

  LabImageActiveArguments({
    required this.patient,
    required this.record,
    required this.images,
    this.selectedImageIndex,
    this.patientType,
    this.projectCode,
  });
}

class ImagePostProcessTask {
  String imageCode = "";
  ImagePostProcessTaskEnum taskType = ImagePostProcessTaskEnum.DrawURMResult;
  ImagePostProcessTask({required this.imageCode, required this.taskType});
}

enum ImagePostProcessTaskEnum { DrawURMResult, LoadURMParam }
