<template>
  <rect
    @click="emit('click')"
    v-bind="rectBound"
    :rx="style.rectRadius"
    :ry="style.rectRadius"
    :fill="style.rectBgColor"
    :stroke="style.rectBorderColor"
    :stroke-width="style.rectBorderWidth"
  >
  </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="style.rectBgColor"
      :stroke="style.rectBorderColor"
      :stroke-width="style.rectBorderWidth"
      @click="emit('clickHost', step.raw.hosts[index])"
    >
    </rect>

    <text
      v-for="(hostTex, i) in hostTextAttribs"
      @click="emit('clickHost', step.raw.hosts[i])"
      :font-family="fontFamily"
      :fill="style.textColor"
      dominant-baseline="middle"
      :font-size="hostFontSize"
      text-anchor="middle"
      v-bind="hostTex"
    >
      {{ 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"
  >
    {{ step.name }}
  </text>

  <template v-if="lines.length">
    <polyline
      v-for="line in lines"
      :points="line.join(',')"
      fill="none"
      :stroke="style.lineColor"
      :stroke-width="style.lineWidth"
    />
  </template>
</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[];
  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 / 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 / 2,
  }))
);
</script>
