import 'dart:ui';

import 'package:fis_measure/interfaces/date_types/point.dart';
import 'package:fis_measure/interfaces/enums/items.dart';
import 'package:fis_measure/interfaces/process/items/item.dart';
import 'package:fis_measure/interfaces/process/items/item_metas.dart';
import 'package:fis_measure/interfaces/process/items/types.dart';
import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
import 'package:fis_measure/process/calcuators/heart_rate.dart';
import 'package:fis_measure/process/items/item.dart';
import 'package:fis_measure/utils/canvas.dart';
import 'package:fis_measure/view/gesture/cross_position_indicator.dart';
import 'package:fis_measure/view/gesture/positioned_cursor.dart';
import 'package:fis_measure/view/gesture/positioned_touch_cursor.dart';
import 'package:fis_ui/index.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:vid/us/vid_us_mode.dart';
import '../items/item_feature.dart';

/// 只绘制一次直线,即会自动开始,不会自动结束
class SingleStraightLine extends MeasureItem<SingleStraightLineFeature> {
  late final mouseState = Get.find<IMouseState>();
  late final touchState = Get.find<ITouchPointState>();

  SingleStraightLine(ItemMeta meta, IMeasureItem? parent) : super(meta, parent);

  static SingleStraightLine createHeartRate(ItemMeta meta,
      [IMeasureItem? parent]) {
    SingleStraightLine straightLine = SingleStraightLine(meta, parent);
    straightLine.calculator = HeartRateCal(straightLine);
    final point = DPoint(0, 0);
    straightLine.feature = StraightLineHeartRateFeature(
        straightLine, point, point, straightLine.doCalculate,
        ifHorizontal: false);
    return straightLine;
  }

  @override
  bool onExecuteMouse(PointInfo args) {
    if (state == ItemStates.waiting) {
      startMeasure(args);
    } else if (state == ItemStates.running) {
      if (args.pointType == PointInfoType.mouseUp) return false;
      feature?.endPoint = args;
      doCalculate();
      if (args.pointType == PointInfoType.mouseDown) {
        state = ItemStates.idle;

        ///重置十字样式
        changeCrossIndicatorStyle(CrossIndicatorStyle.nomal);
      }
    } else if (state == ItemStates.idle) {
      if (args.pointType == PointInfoType.mouseDown) {
        feature?.startPoint = args;
        feature?.endPoint = args;
        state = ItemStates.running;

        ///设置十字样式
        changeCrossIndicatorStyle(CrossIndicatorStyle.vertical);
      }
    }
    return true;
  }

  bool isSetStyleOnMoveStart = false;

  @override
  bool onExecuteTouch(PointInfo args) {
    if (state == ItemStates.finished || state == ItemStates.waiting) {
      if (args.pointType == PointInfoType.touchDown) {
        startMeasure(args);
        state = ItemStates.running;
      }
    }
    if (state == ItemStates.running) {
      feature?.startPoint = args;
      feature?.endPoint = args;
      doCalculate();
      if (args.pointType == PointInfoType.touchUp) {
        state = ItemStates.idle;
      }
    } else if (state == ItemStates.idle) {
      feature?.endPoint = args;
      doCalculate();
      if (args.pointType == PointInfoType.touchUp) {
        state = ItemStates.running;
      }

      // 设置十字样式
      if (args.pointType == PointInfoType.touchDown) {
        isSetStyleOnMoveStart = false;
      }
      if (args.pointType == PointInfoType.touchMove && !isSetStyleOnMoveStart) {
        changeCrossIndicatorStyle(CrossIndicatorStyle.vertical);
        isSetStyleOnMoveStart = true;
      }
    }
    return true;
  }

  void changeCrossIndicatorStyle(CrossIndicatorStyle e) {
    if (kIsMobile) {
      touchState.crossIndicatorStyleChanged.emit(this, e);
    } else {
      mouseState.crossIndicatorStyleChanged.emit(this, e);
    }
  }

  void startMeasure(PointInfo args) {
    final point = DPoint(0, 0);
    if (args.hostVisualArea != null) {
      handleTissueTM(args.hostVisualArea!.mode.modeType, point);
      feature!.hostVisualArea = args.hostVisualArea;
    }
    state = ItemStates.idle;
  }

  /// 处理TissueTimeMotion模式
  void handleTissueTM(VidUsModeType mode, DPoint point) {
    if (mode == VidUsModeType.TissueTM || mode == VidUsModeType.Doppler) {
      switch (meta.measureType) {
        case MeasureTypes.HR:
          changeCrossIndicatorStyle(CrossIndicatorStyle.vertical);
          break;
        default:
      }
    } else {
      feature = SingleStraightLineFeature(this, point, point);
    }
  }
}

class SingleStraightLineFeature extends MeasureItemFeature {
  SingleStraightLineFeature(
    IMeasureItem refItem,
    DPoint startPoint,
    DPoint endPoint,
  ) : super(refItem) {
    innerPoints.add(startPoint);
    innerPoints.add(endPoint);
  }

  /// 起点
  DPoint get startPoint => innerPoints[0];
  set startPoint(DPoint value) => innerPoints[0] = value;

  /// 终点
  DPoint get endPoint => innerPoints[1];
  set endPoint(DPoint value) => innerPoints[1] = value;

  /// 长度
  double get length => (endPoint - startPoint).length;

  @override
  void paint(Canvas canvas, Size size) {
    if (startPoint == endPoint && kIsWeb) return;

    drawId(canvas, size, idText);

    final startOffset = convert2ViewPoint(size, startPoint).toOffset();
    drawVertex(canvas, startOffset);

    final endOffset = convert2ViewPoint(size, endPoint).toOffset();
    canvas.drawDashLine(startOffset, endOffset, 1, 10, paintLinePan);
    drawVertex(canvas, endOffset, isActive);
  }
}

class StraightLineHeartRateFeature extends SingleStraightLineFeature {
  StraightLineHeartRateFeature(
      IMeasureItem refItem, DPoint startPoint, DPoint endPoint, this.calculate,
      {this.ifHorizontal = true})
      : super(refItem, startPoint, endPoint);

  ///心脏周期
  int heartCycle = 1;
  final bool ifHorizontal;
  final Function calculate;
  void setHeartRate(int cycle) {
    heartCycle = cycle;
    calculate();
  }

  @override
  void paint(Canvas canvas, Size size) {
    if (startPoint == endPoint && kIsWeb) return;

    drawId(canvas, size, idText);
    final startOffset = convert2ViewPoint(size, startPoint).toOffset();
    final endOffset = convert2ViewPoint(size, endPoint).toOffset();
    if (ifHorizontal) {
      drawMark(canvas, startOffset);
      drawMark(canvas, Offset(startOffset.dx, endOffset.dy), isActive);
    } else {
      drawMark(canvas, startOffset, false, ifHorizontal);
      drawMark(
          canvas, Offset(endOffset.dx, startOffset.dy), isActive, ifHorizontal);
    }
  }
}