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/terms.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/time_motion.dart';
import 'package:fis_measure/process/items/item.dart';
import 'package:fis_measure/process/primitives/combos/depth2baseline.dart';
import 'package:fis_measure/process/primitives/location.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:get/get.dart';
import 'package:vid/us/vid_us_mode.dart';

import '../calcuators/distance.dart';
import '../items/item_feature.dart';

/// 直线
class StraightLine extends MeasureItem<StraightLineFeature> {
  late final mouseState = Get.find<IMouseState>();
  StraightLine(ItemMeta meta, IMeasureItem? parent) : super(meta, parent);

  static StraightLine createDistance(ItemMeta meta, [IMeasureItem? parent]) {
    StraightLine sraightLine = StraightLine(meta, parent);
    sraightLine.calculator = DistanceCal(sraightLine);
    return sraightLine;
  }

  static StraightLine createVerticalDistance(ItemMeta meta,
      [IMeasureItem? parent]) {
    StraightLine sraightLine = StraightLine(meta, parent);
    sraightLine.calculator = VerticalDistanceCal(sraightLine);
    return sraightLine;
  }

  static StraightLine createTimeSpan(ItemMeta meta, [IMeasureItem? parent]) {
    StraightLine sraightLine = StraightLine(meta, parent);
    sraightLine.calculator = TimeSpanCal(sraightLine);
    return sraightLine;
  }

  @override
  bool onExecuteMouse(PointInfo args) {
    if (state == ItemStates.finished) {
      if (args.pointType == PointInfoType.mouseDown) {
        state = ItemStates.waiting;
      }
    }

    if (state == ItemStates.waiting) {
      if (args.pointType == PointInfoType.mouseDown) {
        handleMouseDownWhileWaiting(args);
      }
    } else if (state == ItemStates.running) {
      if (args.pointType == PointInfoType.mouseUp) return false;

      feature?.endPoint = args;
      doCalculate();
      if (args.pointType == PointInfoType.mouseDown) {
        doFeatureFinish();

        ///重置十字样式
        mouseState.crossIndicatorStyleChanged
            .emit(this, CrossIndicatorStyle.nomal);
      }
    }
    return true;
  }

  PointInfo? startPoint;
  @override
  bool onExecuteTouch(PointInfo args) {
    if (state == ItemStates.finished) {
      if (args.pointType == PointInfoType.touchDown) {
        state = ItemStates.waiting;
      }
    }

    if (state == ItemStates.waiting) {
      switch (args.pointType) {
        case PointInfoType.touchDown:
          startPoint = args; // 设置线段起点
          break;
        case PointInfoType.touchUp:
          break; // 按下立即抬起无事发生
        case PointInfoType.touchMove:
          handleMouseDownWhileWaiting(startPoint!); // 通过设置的起点开始一个绘制事件
          break;
        default:
          break;
      }
    } else if (state == ItemStates.running) {
      if (args.pointType == PointInfoType.touchUp) {
        doFeatureFinish();
      }
      if (args.pointType == PointInfoType.touchMove) {
        doCalculate();
        feature?.endPoint = args;
      }
    }
    return true;
  }

  void handleMouseDownWhileWaiting(PointInfo args) {
    // TODO: 判断是否当前area
    // 转换为Area逻辑位置
    final point = args.toAreaLogicPoint();
    // feature = StraightLineFeature(this, point, point);
    if (args.hostVisualArea != null) {
      handleTissueTM(args.hostVisualArea!.mode.modeType, point);
      feature!.hostVisualArea = args.hostVisualArea;
    }
    state = ItemStates.running;
  }

  /// 处理TissueTimeMotion模式
  void handleTissueTM(VidUsModeType mode, DPoint point) {
    if (mode == VidUsModeType.TissueTM) {
      switch (meta.measureType) {
        case MeasureTypes.TimeSpan:
          feature = StraightLineTimeMotionFeature(this, point, point,
              ifHorizontal: false);
          mouseState.crossIndicatorStyleChanged
              .emit(this, CrossIndicatorStyle.vertical);
          break;
        case MeasureTypes.VerticalDistance:
          feature = StraightLineTimeMotionFeature(this, point, point);
          mouseState.crossIndicatorStyleChanged
              .emit(this, CrossIndicatorStyle.horizontal);
          break;
        default:
      }
    } else {
      feature = StraightLineFeature(this, point, point);
    }
  }
}

class StraightLineFeature extends MeasureItemFeature {
  StraightLineFeature(
    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) return;

    var idText = '$id.${refItem.briefAnnotation}';
    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, paintPan);
    drawVertex(canvas, endOffset, isActive);
  }
}

class StraightLineTimeMotionFeature extends StraightLineFeature {
  StraightLineTimeMotionFeature(
      IMeasureItem refItem, DPoint startPoint, DPoint endPoint,
      {this.ifHorizontal = true})
      : super(refItem, startPoint, endPoint);
  final bool ifHorizontal;
  @override
  void paint(Canvas canvas, Size size) {
    if (startPoint == endPoint) return;
    var idText = '$id';
    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);
    }
  }
}