import 'dart:async';
import 'dart:convert';
import 'dart:ui' as ui;
import 'package:fis_common/event/event_type.dart';
import 'package:fis_jsonrpc/services/index.dart';
import 'package:fis_measure/interfaces/process/workspace/measure_3d_view_controller.dart';
import 'package:fis_measure/utils/js_utils.dart'
    if (dart.library.io) 'package:fis_measure/utils/js_utils4native.dart'
    if (dart.library.html) 'package:fis_measure/utils/js_utils.dart';
import 'package:flutter/material.dart';

import 'package:vid/us/vid_us_image.dart';

class Measure3DViewController implements IMeasure3DViewController {
  Measure3DViewController();

  /// [Carotid] ✅Measure3DView 控制器
  CarotidResultDTO _carotidResult = CarotidResultDTO();
  String _recordId = "";
  List<Ultra3DResourceInfo> _ultra3DResourceInfoList = [];
  bool _exist3DData = false;
  bool _enable2DMeasure = false;
  bool isShell = ifCurEnvIsShell;
  bool needAutoDetection = false;

  /// 模型切面标准宽度
  Size stdSize = const Size(599, 400);
  VidUsImage? _image4Measure;
  MeasureMode _curMeasureMode = MeasureMode.vidMode;

  ///3D模式下进入颈动脉2D模式
  void changeModeTo2DMeasure() {
    curMeasureMode = MeasureMode.carotid2DMode;
    // initParams();
    updatePlayerMode.emit(this, MeasureMode.carotid2DMode);
  }

  ///vid 2D模式下进入3D测量模式
  void changeModeTo3DMode() {
    curMeasureMode = MeasureMode.carotid3DMode;
    // initParams();
    updatePlayerMode.emit(this, MeasureMode.carotid3DMode);
  }

  ///颈动脉 2D模式下回到3D测量模式
  void backTo3DMode() {
    curMeasureMode = MeasureMode.carotid3DMode;
    updatePlayerMode.emit(this, MeasureMode.carotid3DMode);
  }

  /// 颈动脉2D、3D模式回到vid 2D测量模式
  void backToVidMode() {
    // initParams();
    resetTone();
    curMeasureMode = MeasureMode.vidMode;
    updatePlayerMode.emit(this, MeasureMode.vidMode);
  }

  ///[Carotid] ✅通知 shell 下载全部模型文件,_ultra3DResourceInfoList 中的第一个元素为当前操作的元素
  void notifyShellLoadAllModel() {
    if (_ultra3DResourceInfoList.isNotEmpty) {
      final Ultr3DParameter ultra3DParameter =
          Ultr3DParameter(_recordId, _ultra3DResourceInfoList);
      callShellMethod("setUltr3DData", [ultra3DParameter.toJson()]);
    }
  }

  /// [Carotid] ✅通知 shell 切换到当前所选模型,本质调用了同一个接口
  void notifyShellSetCurModel() {
    final Ultr3DParameter ultra3DParameter =
        Ultr3DParameter(_recordId, [Ultra3DResourceInfo(_carotidResult)]);
    callShellMethod("setUltr3DData", [ultra3DParameter.toJson()]);
  }

  /// [Carotid] ✅shell 通知 webview 切换到当前所选模型
  void handleMdlFileLoaded(String loadedMdlFile) {
    if (loadedMdlFile == carotidResult.mdlFile) {
      onShellLoadedMdlFile.emit(this, null);
    }
  }

  /// [Carotid] ✅shell 通知 flutter 修改测量中的颈动脉2D图像
  void handleUpdateCarotid2DImage(String base64Image) {
    if (curMeasureMode == MeasureMode.carotid2DMode) {
      onUpdateCarotid2DImage.emit(this, base64Image);
    }
  }

  var onUpdateCarotid2DImage = FEventHandler<String>();

  /// 用户主动触发更换颈动脉图像
  var onChangeCarotid2DImage = FEventHandler<String>();
  void handleChangeCarotid2DImage(String recordId) {
    initParams();
    onChangeCarotid2DImage.emit(this, recordId);
  }

  /// [Carotid] ✅模型切换时初始化一些参数
  void initParams() {
    enable2DMeasure = false;
  }

  @override
  CarotidResultDTO get carotidResult => _carotidResult;

  @override
  var updatePlayerMode = FEventHandler<MeasureMode>();

  @override
  var onShellLoadedMdlFile = FEventHandler<void>();

  var adjustPlaneImage = FEventHandler<ImageAdjustPara>();

  @override
  set carotidResult(CarotidResultDTO value) {
    if (value != _carotidResult) {
      _carotidResult = value;
    }
  }

  @override
  bool get exist3DData => _exist3DData;
  @override
  set exist3DData(bool value) {
    if (value != _exist3DData) {
      _exist3DData = value;
    }
  }

  @override
  bool get enable2DMeasure => _enable2DMeasure;
  @override
  set enable2DMeasure(bool value) {
    if (value != _enable2DMeasure) {
      _enable2DMeasure = value;
    }
  }

  @override
  VidUsImage? get image4Measure => _image4Measure;
  @override
  set image4Measure(VidUsImage? value) {
    if (value != _image4Measure) {
      _image4Measure = value;
    }
  }

  @override
  String get recordId => _recordId;
  @override
  set recordId(String value) {
    if (value != _recordId) {
      _recordId = value;
    }
  }

  @override
  List<Ultra3DResourceInfo> get ultra3DResourceInfoList =>
      _ultra3DResourceInfoList;
  @override
  set ultra3DResourceInfoList(List<Ultra3DResourceInfo> value) {
    if (value != _ultra3DResourceInfoList) {
      _ultra3DResourceInfoList = value;
    }
  }

  @override
  MeasureMode get curMeasureMode => _curMeasureMode;
  @override
  set curMeasureMode(MeasureMode value) {
    if (value != _curMeasureMode) {
      _curMeasureMode = value;
    }
  }

  /// 当前3D模型切面的亮度、对比度、锐度 :初始值、最大值、最小值、标准值
  /// 控件传入的值范围都是 -100 ~ 100 需要手动转换
  int _sharpness = 0; //0,200,-200,0
  int _brightness = 0; //0,255,-255,0
  int _contrast = 100; //100,400,0,100

  int get sharpness => _sharpness;
  set sharpness(int value) {
    _sharpness = value * 2;
  }

  int get brightness => _brightness;
  set brightness(int value) {
    _brightness = (value * 2.55).toInt();
  }

  int get contrast => _contrast;
  set contrast(int value) {
    if (value <= 0) {
      _contrast = value + 100;
    } else {
      _contrast = value * 3 + 100;
    }
  }

  var onResetTone = FEventHandler<void>();

  /// 重置图像增益
  void resetTone() {
    sharpness = 0;
    brightness = 0;
    contrast = 0;
    notifyShellSetTone();
    onResetTone.emit(this, null);
  }

  ImageAdjustPara curImageAdjustPara =
      ImageAdjustPara(brightness: 0, contrast: 100, sharpness: 0);

  /// [Carotid] ✅通知 shell 设置图像增益,并且直接调整 webview 中的图像增益, 如果在2D测量模式下,则刷新图像
  void notifyShellSetTone() {
    //如果参数没变,不刷新
    if (sharpness == curImageAdjustPara.sharpness &&
        brightness == curImageAdjustPara.brightness &&
        contrast == curImageAdjustPara.contrast) {
      return;
    }
    final ImageAdjustPara params = ImageAdjustPara(
        brightness: brightness, contrast: contrast, sharpness: sharpness);
    curImageAdjustPara = params;
    adjustPlaneImage.emit(this, params);
    if (curMeasureMode == MeasureMode.carotid2DMode) {
      callShellMethod("getCurrentPlaneWithGivenPara", [params.toJson()]);
    }
  }
}

/// Shell 内的增益调整参数模型
class ImageAdjustPara {
  int brightness;
  int contrast;
  int sharpness;

  ImageAdjustPara(
      {required this.brightness,
      required this.contrast,
      required this.sharpness});

  String toJson() {
    return json.encode({
      "Brightness": brightness,
      "Contrast": contrast,
      "Sharpness": sharpness,
    });
  }
}

///获取图片尺寸
Future<Size> loadImageSize(String url) async {
  ui.Image image = await getImage(url);
  final width = image.width;
  final height = image.height;
  image.dispose();
  return Size(width.toDouble(), height.toDouble());
}

Future<ui.Image> getImage(String path) async {
  var completer = Completer<ImageInfo>();
  var img = NetworkImage(path);
  img
      .resolve(const ImageConfiguration())
      .addListener(ImageStreamListener((info, _) {
    completer.complete(info);
  }));
  ImageInfo imageInfo = await completer.future;
  return imageInfo.image;
}