<template>
  <rect
    @click="emit('click')"
    v-bind="rectBound"
    :rx="style.rectRadius"
    :ry="style.rectRadius"
    :fill="style.rectBgColor"
    :stroke="style.rectBorderColor"
    :stroke-width="style.rectBorderWidth"
    style="cursor: pointer"
  >
  </rect>

  <template v-if="lines.length">
    <polyline
      v-for="line in lines"
      :points="line.join(',')"
      fill="none"
      :stroke="style.lineColor"
      :stroke-width="style.lineWidth"
    />
  </template>
  <rect
    v-if="step.treeBound !== step.bound"
    :x="step.treeBound.left + margin[0] - treeBoxMargin[0]"
    :y="step.treeBound.top + margin[1] - treeBoxMargin[1]"
    :width="step.treeBound.width - 2 * margin[0] + 2 * treeBoxMargin[0]"
    :height="step.treeBound.height - 2 * margin[1] + 2 * treeBoxMargin[1]"
    stroke="rgba(0, 0, 0, 0.5)"
    stroke-dasharray="5, 5"
    fill="rgba(0, 0, 0, 0)"
  >
  </rect>

  <template v-if="step.raw.hosts">
    <rect
      v-for="(_, index) in step.raw.hosts"
      :x="hostBounds[index].x"
      :y="hostBounds[index].y"
      :width="hostBounds[index].width"
      :height="hostBounds[index].height"
      :rx="style.rectRadius"
      :ry="style.rectRadius"
      :fill="
        _.status === 'success'
          ? '#30d567'
          : _.status === 'error'
          ? '#ff4238'
          : _.status === 'running'
          ? '#ecf752'
          : _.status === 'waiting'
          ? '#89beb2'
          : 'd4f8c3'
      "
      :stroke="'#333'"
      :stroke-width="style.rectBorderWidth"
      @click="emit('clickHost', step.raw.hosts[index])"
      style="cursor: pointer"
    >
    </rect>

    <text
      v-for="(hostTex, i) in hostTextAttribs"
      @click="emit('clickHost', step.raw.hosts[i])"
      :font-family="fontFamily"
      :fill="'#333'"
      dominant-baseline="middle"
      :font-size="hostFontSize"
      text-anchor="middle"
      v-bind="hostTex"
      style="cursor: pointer"
    >
      {{ step.raw.hosts[i].host }}
    </text>
  </template>
  <text
    @click="emit('click')"
    :font-family="fontFamily"
    :fill="style.textColor"
    :font-size="fontSize"
    dominant-baseline="middle"
    text-anchor="middle"
    v-bind="textAttrib"
    style="cursor: pointer"
  >
    {{ step.displayName }}
  </text>
</template>

<script setup lang="ts">
import { computed } from "vue";
import { NStep } from "./helper";

const props = defineProps<{
  step: NStep;
  margin: number[];
  padding: number[];
  fontSize: number;
  fontFamily: string;
  lines: number[][];
  hostMargin: number[];
  hostPadding: number[];
  treeBoxMargin: number[];
  hostFontSize: number;
  style: {
    lineColor: string;
    lineWidth: number;
    textColor: string;
    rectBorderColor: string;
    rectBorderWidth: number;
    rectBgColor: string;
    rectRadius: number;
  };
}>();

const emit = defineEmits<{ (e: "click"): void; (e: "clickHost", host: any): void }>();

const rectBound = computed(() => ({
  x: props.step.bound.left + props.margin[1],
  y: props.step.bound.top + props.margin[0],
  width: props.step.bound.width - props.margin[1] * 2,
  height: props.step.bound.height - props.margin[0] * 2,
}));
const textAttrib = computed(() => ({
  x: rectBound.value.x + rectBound.value.width / 2,
  y: rectBound.value.y + props.padding[0] + props.fontSize / 1.2,
}));

const hostBounds = computed(() => {
  let left =
    rectBound.value.x +
    props.padding[1] +
    (rectBound.value.width - props.padding[1] * 2 - props.step.raw.hostSize.width) / 2;
  let top = rectBound.value.y + rectBound.value.height - props.step.raw.hostSize.height;

  const hosts = props.step.raw.hosts;
  return hosts.map((host: any) => {
    const x = left + host.bound.left + props.hostMargin[1];
    const y = top + props.hostMargin[0] + host.bound.top;
    return {
      x,
      y,
      width: host.bound.width - props.hostMargin[1] * 2,
      height: host.bound.height - props.hostMargin[0] * 2,
    };
  });
});
const hostTextAttribs = computed(() =>
  hostBounds.value.map((hostBound: any) => ({
    x: hostBound.x + hostBound.width / 2,
    y: hostBound.y + props.hostPadding[0] + props.hostFontSize / 1.2,
  }))
);
</script>
