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/visuals/visual_area.dart';
import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
import 'package:fis_measure/process/items/item.dart';
import 'package:fis_measure/view/canvas/utils.dart';

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

class StraightLine extends MeasureItem<StraightLineFeature> {
  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;
  }

  @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();
      }
    }
    return true;
  }

  @override
  bool onExecuteTouch(PointInfo args) {
    // TODO: implement onExecuteTouch
    throw UnimplementedError();
  }

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

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;

    const double vertexSize = 10;

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

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