import { GraphModel, h, RectNode, RectNodeModel } from "@logicflow/core";
import { ColorEnum, NodeSizeEnum, NodeStateEnum } from "../types/enums";

class SubProcessModel extends RectNodeModel {
  constructor(data: any, graphModel: GraphModel) {
    super(data, graphModel);
  }

  setAttributes(): void {
    if((this.text && this.text.value == "") || !this.text) {
      this.text.value = "子流程";
    }

    if (this.properties._width) {
      this.width = this.properties._width;
    } else {
      this.width = NodeSizeEnum.width;
    }

    if (this.properties._height) {
      this.height = this.properties._height;
    } else {
      this.height = NodeSizeEnum.height;
    }

    if (this.properties._radius !== undefined) {
      this.radius = this.properties._radius;
    } else {
      this.radius = 4;
    }

    if (this.properties._stroke) {
      this.properties.stroke = this.properties._stroke;
    }
    if (this.properties._fill) {
      this.properties.fill = this.properties._fill;
    }
    if (this.properties._strokeWidth) {
      this.properties.strokeWidth = this.properties._strokeWidth;
    }
    if (this.properties._opacity) {
      this.properties.opacity = this.properties._opacity;
    }
  }

  getNodeStyle() {
    const style = super.getNodeStyle();
    const state = this.properties.state;

    if(state === NodeStateEnum.history) {
      style.stroke = ColorEnum.historyColor;
      style.fill = `${ColorEnum.historyColor}10`;
    } else if(state === NodeStateEnum.active) {
      style.stroke = ColorEnum.activeColor;
      style.fill = `${ColorEnum.activeColor}10`;
    } else if(state === NodeStateEnum.error) {
      style.stroke = ColorEnum.errorColor;
      style.fill = `${ColorEnum.errorColor}10`;
    } else {
      style.stroke = '#909399';
      style.fill = '#f5f5f5';
    }

    if (this.properties._stroke) {
      style.stroke = this.properties._stroke;
    }
    if (this.properties._fill) {
      style.fill = this.properties._fill;
    }
    if (this.properties._strokeWidth) {
      style.strokeWidth = this.properties._strokeWidth;
    }
    if (this.properties._opacity !== undefined) {
      style.opacity = this.properties._opacity;
    }

    return style;
  }
}

class SubProcessView extends RectNode {
  private getSubProcessIcon() {
    const { model } = this.props;
    const { x, y, width } = model;
    const style = model.getNodeStyle();
    const iconSize = 16;
    const padding = 8;

    const centerX = x - width / 2 + padding + iconSize / 2;
    const centerY = y;
    const boxWidth = iconSize * 0.7;
    const boxHeight = iconSize * 0.5;
    const plusSize = 4;

    return h("g", {}, [
      h("rect", {
        x: centerX - boxWidth / 2,
        y: centerY - boxHeight / 2,
        width: boxWidth,
        height: boxHeight,
        fill: "none",
        stroke: style.stroke,
        strokeWidth: 1.5,
        rx: 2,
        ry: 2
      }),
      h("line", {
        x1: centerX - plusSize / 2,
        y1: centerY,
        x2: centerX + plusSize / 2,
        y2: centerY,
        stroke: style.stroke,
        strokeWidth: 1.5,
        strokeLinecap: "round"
      }),
      h("line", {
        x1: centerX,
        y1: centerY - plusSize / 2,
        x2: centerX,
        y2: centerY + plusSize / 2,
        stroke: style.stroke,
        strokeWidth: 1.5,
        strokeLinecap: "round"
      })
    ]);
  }

  private getLeftBar() {
    const { model } = this.props;
    const { x, y, width, height } = model;
    const style = model.getNodeStyle();
    const barWidth = 3;

    return h("rect", {
      x: x - width / 2,
      y: y - height / 2,
      width: barWidth,
      height,
      rx: 1.5,
      ry: 1.5,
      fill: style.stroke,
      opacity: 0.7
    });
  }

  getResizeShape() {
    const { model } = this.props;
    const { x, y, width, height, radius } = model;
    const style = model.getNodeStyle();
    return h("g", {}, [
      h("rect", {
        ...style,
        x: x - width / 2,
        y: y - height / 2,
        rx: radius,
        ry: radius,
        width,
        height
      }),
      this.getLeftBar(),
      this.getSubProcessIcon()
    ]);
  }

  getShape() {
    return this.getResizeShape();
  }
}

export default {
  type: "subProcess",
  view: SubProcessView,
  model: SubProcessModel,
};
