import 'dart:developer';
import 'package:fis_common/index.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_measure/interfaces/process/workspace/exam_info.dart';
import 'package:fis_measure/interfaces/process/workspace/measure_3d_view_controller.dart';
import 'package:fis_measure/process/layout/configuration.dart';
import 'package:fis_measure/process/workspace/measure_controller.dart';
import 'package:fis_measure/process/workspace/measure_data_controller.dart';
import 'package:fis_measure/process/workspace/measure_data_helper.dart';
import 'package:fis_measure/process/workspace/measure_handler.dart';
import 'package:fis_measure/process/workspace/measure_3d_view_controller.dart';
import 'package:fis_measure/view/gesture/positioned_cursor.dart';
import 'package:fis_measure/view/measure/measure_config/widgets/measure_configuration_style.dart';
import 'package:fis_measure/view/measure/measure_images_bar.dart';
import 'package:fis_measure/view/measure/measure_player.dart';
import 'package:fis_measure/view/measure/measure_tool_panel.dart';
import 'package:fis_measure/view/measure/measure_view_controller.dart';
import 'package:fis_measure/view/player/control_board/operate_bar.dart';
import 'package:fis_ui/index.dart';
import 'package:fis_ui/interface/interactive_container.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

/// 测量主页面
class MeasureMainPage extends StatefulWidget
    implements FWidget, FInteractiveContainer {
  const MeasureMainPage(
    this.token,
    this.recordCode,
    this.patientCode,
    this.remedicalCode, {
    this.needRouterBack,
    this.enableLoopPlayback = false,
    this.onLoopPlaybackEnableChanged,
    this.remedicalAISelectedInfoCode,
    this.customWidgets = const [],
    this.hasQualityControlPermission = false,
    this.dispose,
    Key? key,
  }) : super(key: key);

  final String token;
  final String patientCode;
  final String remedicalCode;
  final String recordCode;
  final bool? needRouterBack; // 需要返回按钮【一版用于返回到报告编辑】
  final bool enableLoopPlayback;
  final ValueCallback<bool>? onLoopPlaybackEnableChanged;
  final String? remedicalAISelectedInfoCode;
  final List<FWidget> customWidgets;
  final bool hasQualityControlPermission;
  final void Function()? dispose;

  @override
  final String pageName = 'MeasureMainPage';
  @override
  State<StatefulWidget> createState() => _MeasureMainPageState();
}

class _MeasureMainPageState extends State<MeasureMainPage> {
  /// 病人及图像信息
  // String _curToken = '';
  String _curPatientCode = '';
  String _curRemedicalCode = '';
  String _curRecordCode = '';
  String? _curRemedicalAISelectedInfoCode = '';
  bool? _curNeedRouterBack;

  /// 数据
  final measureData = Get.find<MeasureDataController>();

  /// webview 控制器
  final measure3DViewController = Get.find<Measure3DViewController>();

  /// 测量项控制器
  final measureMetaController = Get.put(MeasureMetaController());
  double get devicePixelRatio =>
      kIsMobile ? 1 : MediaQuery.of(context).devicePixelRatio;

  /// 隐藏全屏loadding
  bool _hideFullScreenLoading = false;

  /// 图片loadding
  late bool imageLoading = false;

  late final measureHandler = Get.find<MeasureHandler>();

  /// 测量控制器
  late MeasureController measureController;

  /// 响应图片切换事件通知
  void _onNewImageLoadStatueChanged(sender, e) {
    imageLoading = e;
    setState(() {});
  }

  /// 响应全屏状态切换事件
  void _onChangeFullScreenState(sender, e) {
    setState(() {});
  }

  /// 响应工具面板状态切换事件
  void _onToolPanelStateChanged(sender, e) {
    setState(() {});
  }

  /// 在此处动态刷新测量窗口,而不是重置窗口
  void _onUpdateState(sender, Map<String, String> parameters) async {
    _curNeedRouterBack = false;
    bool needUpdate = false;
    if (_curRecordCode == (parameters['recordCode'] ?? '')) {
      if (_curRemedicalCode == (parameters['remedicalCode'] ?? '')) {
      } else {
        measureHandler.changeImageByRemedicalCode
            .emit(this, parameters['remedicalCode'] ?? '');
      }
    } else {
      needUpdate = true;
    }
    // _curToken = parameters['token'] ?? '';
    _curPatientCode = parameters['patientCode'] ?? '';
    _curRemedicalCode = parameters['remedicalCode'] ?? '';
    _curRecordCode = parameters['recordCode'] ?? '';
    _curRemedicalAISelectedInfoCode =
        parameters['remedicalAISelectedInfoCode'] ?? '';

    if (needUpdate) {
      await LayoutConfiguration.ins.loadData();
      List<RemedicalInfoDTO> remedicals = await _getCurRemedicals();
      _initMouseModuel();
      _initCarotidModuel(remedicals);
      measureData.remedicalList = remedicals;
      var remedicalInfo = await MeasureDataHelper.getImageInfo
          .call(_curRemedicalCode, _curRemedicalAISelectedInfoCode);
      if (remedicalInfo != null) {
        measureData.aiResults = remedicalInfo.diagnosisResult ?? '';
        if (remedicalInfo.terminalImages != null) {
          _hideFullScreenLoading = true;
          measureData.itemCurrentImage =
              measureData.chooseImageUrl(remedicalInfo.terminalImages!);
          getExamImageInfoList(remedicals);
          measureHandler.changeImageList.emit(this, remedicals);
        }
      }

      measureController.imageLoaded.removeListener(_onImageLoaded);
      measureController.imageLoaded.addListener(_onImageLoaded);
    }
    _setCurImageData();
  }

  /// 将当前的图像信息同步到 measureData 中
  void _setCurImageData() {
    measureData.measureInfoData = MeasureInfoData(
      patientCode: _curPatientCode,
      recordCode: _curRecordCode,
      remedicalCode: _curRemedicalCode,
      remedicalAISelectedInfoCode: _curRemedicalAISelectedInfoCode,
    );
  }

  /// 先加载图像布局配置,然后加载全局数据
  void _loadLayoutConfig() async {
    await LayoutConfiguration.ins.loadData();
    setState(() {
      _initData();
    });
  }

  @override
  void initState() {
    _curPatientCode = widget.patientCode;
    _curRemedicalCode = widget.remedicalCode;
    _curRecordCode = widget.recordCode;
    _curNeedRouterBack = widget.needRouterBack;
    _curRemedicalAISelectedInfoCode = widget.remedicalAISelectedInfoCode;
    _hideFullScreenLoading = false;
    _loadLayoutConfig();
    _setCurImageData();
    measureData.curMeasureDataChanged.addListener(_onUpdateState);
    measureHandler.onNewImageLoadStatueChanged
        .addListener(_onNewImageLoadStatueChanged);
    measureHandler.onChangeFullScreenState
        .addListener(_onChangeFullScreenState);
    measureHandler.onToolPanelStateChanged
        .addListener(_onToolPanelStateChanged);
    super.initState();
  }

  @override
  void dispose() {
    measureData.curMeasureDataChanged.removeListener(_onUpdateState);
    measureHandler.onNewImageLoadStatueChanged
        .removeListener(_onNewImageLoadStatueChanged);
    measureHandler.onChangeFullScreenState
        .removeListener(_onChangeFullScreenState);
    measureHandler.onToolPanelStateChanged
        .removeListener(_onToolPanelStateChanged);
    widget.dispose?.call();
    super.dispose();
  }

  @override
  FWidget build(BuildContext context) {
    FWidget body;
    if (!_hideFullScreenLoading) {
      const loadingWidget = FCenter(child: FCircularProgressIndicator());
      body = FRow(
        children: const [
          FExpanded(
            child: loadingWidget,
          ),
        ],
      );
    } else {
      body = FColumn(children: [
        FExpanded(
          child: FRow(
            children: [
              FOffstage(
                  child: MeasureToolPanel(
                    customWidgets: widget.customWidgets,
                  ),
                  offstage: measureHandler.fullScreenState ||
                      !measureHandler.toolPanelState),
              const FVerticalDivider(),
              FExpanded(
                child: FColumn(
                  mainAxisSize: MainAxisSize.max,
                  children: [
                    FExpanded(
                        child: FStack(
                      children: [
                        if (!imageLoading)
                          MeasureRightBoard(
                            key: ValueKey(measureData.itemCurrentImage),
                          ),
                        if (imageLoading)
                          FContainer(
                            color: Colors.black,
                            child: const FCenter(
                              child: FCircularProgressIndicator(),
                            ),
                          ),
                      ],
                    )),

                    // if (!measureHandler.fullScreenState) const MeasureImagesBar(),
                  ],
                ),
              ),
            ],
          ),
        ),
        FOffstage(
            child: FRow(children: [
              FColumn(
                children: [
                  const OperateBar(),
                  _curNeedRouterBack ?? false
                      ? FContainer(
                          width: 300 / devicePixelRatio,
                          padding:
                              EdgeInsets.only(bottom: 20 / devicePixelRatio),
                          child: FIconButton(
                            businessParent: widget,
                            name: "back",
                            onPressed: () {
                              Get.back();
                            },
                            icon: const FIcon(
                              Icons.arrow_back,
                              color: Colors.white,
                              size: 36,
                            ),
                          ),
                        )
                      : const FSizedBox()
                ],
              ),
              FExpanded(
                child: MeasureImagesBar(
                  hasQualityControlPermission:
                      widget.hasQualityControlPermission,
                ),
              ),
            ]),
            offstage: measureHandler.fullScreenState),
      ]);
    }
    return FCenter(
      child: FContainer(
        color: _hideFullScreenLoading
            ? const Color.fromRGBO(70, 70, 70, 1)
            : Colors.black,
        child: body,
      ),
    );
  }

  /// 获取当前状态下的图像集
  Future<List<RemedicalInfoDTO>> _getCurRemedicals() async {
    List<RemedicalInfoDTO> remedicals = [];

    var value = await MeasureDataHelper.getRemedicalList(
      _curPatientCode,
      _curRecordCode,
    );

    for (var remedicalItemList in value) {
      remedicals.addAll(remedicalItemList.remedicalList ?? []);
    }

    return remedicals;
  }

  /// 初始化颈动脉模块
  /// [Carotid] ✅遍历出颈动脉信息列表,传给壳子
  void _initCarotidModuel(List<RemedicalInfoDTO> remedicals) {
    List<Ultra3DResourceInfo> ultra3DResourceInfos = [];
    for (var remedical in remedicals) {
      if (remedical.carotidResult != null) {
        ultra3DResourceInfos.add(Ultra3DResourceInfo(remedical.carotidResult!));
      }
    }
    measure3DViewController.ultra3DResourceInfoList = ultra3DResourceInfos;
    measure3DViewController.recordId = _curRecordCode;
    measure3DViewController.notifyShellLoadAllModel();
  }

  /// 初始化卡尺样式部分
  Future<void> _initMouseModuel() async {
    final mouseState = Get.put<IMouseState>(MouseState());
    MeasureSystemSettingDTO result = MeasureSystemSettingDTO(
      cursorSize: 16,
      shapeCursorSize: 30,
      showResultWindow: true,
      fontSize: 14,
      showCursorLine: true,
      showDepthGuideline: true,
      showBriefAnnotation: true,
      autoSnapDistance: '20',
      minCursorDistance: '20',
      annotationFontSize: 14,
      distanceUnit: Unit.cm,
      areaUnit: Unit.cm2,
      velocityUnit: Unit.cms,
      timeUnit: Unit.s,
    );
    try {
      result = await MeasureDataHelper.getMeasureSystemSettingAsync();
    } catch (e) {
      log("getMeasureSystemSettingAsync error: $e");
    }
    measureData.measureSystemSetting = result;
    measureData.checkErrorUnitConfig();
    measureData.checkErrorStyleConfig();
    mouseState.cursorType =
        getMeasureSystemSettingCursorType(result.cursorType);
    mouseState.cursorSize = result.cursorSize.toDouble();
  }

  /// 测量页全局数据首次初始化
  void _initData() async {
    List<RemedicalInfoDTO> remedicals = await _getCurRemedicals();
    _initMouseModuel();
    _initCarotidModuel(remedicals);
    measureData.remedicalList = remedicals;
    var remedicalInfo = await MeasureDataHelper.getImageInfo(
        _curRemedicalCode, _curRemedicalAISelectedInfoCode);
    if (remedicalInfo != null) {
      measureData.aiResults = remedicalInfo.diagnosisResult ?? '';

      if (remedicalInfo.terminalImages != null) {
        _hideFullScreenLoading = true;
        final imgInfo = remedicalInfo.terminalImages!;
        measureData.itemCurrentImage = measureData.chooseImageUrl(imgInfo);
        getExamImageInfoList(remedicals);
      }
    }

    measureController.imageLoaded.removeListener(_onImageLoaded);
    measureController.imageLoaded.addListener(_onImageLoaded);
  }

  /// 获取测量图片所需的图片组 并且写入控制器中 加载
  void getExamImageInfoList(List<RemedicalInfoDTO> remedicals) async {
    /// 检查中图片信息表
    List<ExamImageInfo> examImageInfoList = remedicals.map((e) {
      final imgInfo = e.terminalImages!;
      final vidUrl = measureData.chooseImageUrl(imgInfo);
      return ExamImageInfo(
        vidUrl,
        imgInfo.previewUrl!,
        remedicalCode: e.remedicalCode,
      );
    }).toList();

    Get.delete<MeasureController>();
    measureController = Get.put(MeasureController(
      "",
      imagesFetchFunc: (code) async {
        return examImageInfoList;
      },
      enableLoopPlayback: widget.enableLoopPlayback,
      onLoopPlaybackEnableChanged: widget.onLoopPlaybackEnableChanged,
    ));

    await measureController.load();

    final selectedImageIndex = examImageInfoList.indexWhere(
      (element) => element.url == measureData.itemCurrentImage,
    );
    if (selectedImageIndex > -1) {
      // 命中当前选择图像
      measureController.examInfo.selectedImageIndex = selectedImageIndex;
    }
    // MeasureLanguage.load(measureData.measureLanguage);
  }

  /// vid 切换时会触发到这里
  void _onImageLoaded(Object sender, ExamImageInfo? e) async {
    // measureHandler.changeImageLoaded = true;
    if (!mounted) return;
    final currentImage = measureData.remedicalList.firstWhereOrNull(
      (element) =>
          element.terminalImages!.imageUrl == e!.url ||
          element.terminalImages!.originImageUrl == e.url,
    );
    if (currentImage != null) {
      /// 获取图片详细信息
      var remedicalInfo = await MeasureDataHelper.getImageInfo(
        currentImage.remedicalCode ?? '',
        e!.remedicalCode,
      );
      if (remedicalInfo != null) {
        measureData.aiResults = remedicalInfo.diagnosisResult ?? '';
        measure3DViewController.initParams();

        /// ai 良恶性 判断是否有ai
        measureData.diagnosisConclusion = remedicalInfo.diagnosisConclusion;
        var surfaceFile = remedicalInfo.carotidResult?.surfaceFile;
        var cDNMdlFile = remedicalInfo.carotidResult?.cDNMdlFile;
        if (remedicalInfo.carotidResult != null &&
            surfaceFile.isNotNullOrEmpty &&
            cDNMdlFile.isNotNullOrEmpty) {
          /// [Carotid] ✅详情传入测量信息
          measure3DViewController.carotidResult = remedicalInfo.carotidResult!;

          /// [Carotid] ✅需要在此通知 controller 存在颈动脉信息
          measure3DViewController.exist3DData = true;
          measure3DViewController
              .handleChangeCarotid2DImage(remedicalInfo.recordCode!);
        } else {
          measure3DViewController.exist3DData = false;
        }
        // [Carotid] ✅只要更换图片都要切换到Vid 2D模式
        if (measure3DViewController.curMeasureMode != MeasureMode.vidMode) {
          measure3DViewController.backToVidMode();
        }
        try {
          if (e != null) {
            Future.delayed(const Duration(milliseconds: 100), () {
              measureController.playerController.play();
            });
            setState(() {
              _hideFullScreenLoading = true;
              measureHandler.newImageLoading = false;
            });
          }
        } catch (error) {
          setState(() {
            _hideFullScreenLoading = true;
            measureHandler.newImageLoading = false;
          });
        }
      }
    }
  }
}