<template>
  <div class="steps">
    <div
      v-for="(step, index) in steps"
      :key="index"
      class="step"
      :style="stepStyle(index)"
    >
      <div
        v-if="index > 0"
        :class="[
          'step-line',
          'step-line-before',
          step.preActive ? 'step-line-active' : 'step-line-inactive',
        ]"
      ></div>
      <div
        v-if="steps.length > 1 && index < steps.length - 1"
        :class="[
          'step-line',
          'step-line-after',
          step.nextActive ? 'step-line-active' : 'step-line-inactive',
        ]"
      ></div>
      <template v-if="'nodeName' in step">
        <div
          :class="[
            'step-state',
            step.active ? 'step-state-active' : 'step-state-inactive',
          ]"
        >
          <i class="step-state-icon" />
        </div>
        <div class="step-info">
          <div class="step-info-name">{{ step.nodeName }}</div>
          <div class="step-info-desc">
            <span
              class="step-info-desc-item"
              v-for="(p, i) in step.descriptions"
              :key="i"
              >{{ p }}
            </span>
          </div>
        </div>
      </template>
      <template v-else>
        <div
          v-for="(subStep, i) in step.children"
          :key="i"
          :class="[
            'step',
            'sub-step',
            i === 0 ? 'sub-step-up' : 'sub-step-down',
            subStep.active ? 'sub-step-active' : 'sub-step-inactive',
          ]"
        >
          <div
            v-if="index > 0"
            :class="[
              'step-line',
              'step-line-before',
              subStep.active ? 'step-line-active' : 'step-line-inactive',
            ]"
          ></div>
          <div
            v-if="index < steps.length - 1"
            :class="[
              'step-line',
              'step-line-after',
              subStep.active ? 'step-line-active' : 'step-line-inactive',
            ]"
          ></div>
          <div
            :class="[
              'step-state',
              subStep.active ? 'step-state-active' : 'step-state-inactive',
            ]"
          >
            <i class="step-state-icon" />
          </div>
          <div class="step-info">
            <div class="step-info-name">{{ subStep.nodeName }}</div>
            <div class="step-info-desc">
              <span
                class="step-info-desc-item"
                v-for="(p, i) in subStep.descriptions"
                :key="i"
                >{{ p }}
              </span>
            </div>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import { CSSProperties, PropType } from 'vue'

type StepData = {
  nodeName: string
  active: boolean
  preActive?: boolean
  nextActive?: boolean
  labelWidth?: number
  descriptions: string[]
}
type CombinedStepData = {
  active: boolean
  children: [StepData, StepData]
  labelWidth?: number
  preActive?: boolean
  nextActive?: boolean
}

const props = defineProps({
  steps: {
    type: Array as PropType<(StepData | CombinedStepData)[]>,
    default: () => [],
  },
  hasMultiple: {
    type: Boolean,
    default: false,
  },
})

watchEffect(() => {
  const steps = props.steps
  const { length } = steps
  for (let i = 0; i < length - 1; i++) {
    const currentStep = steps[i]
    const nextStep = steps[i + 1]
    const allActive = currentStep.active && nextStep.active
    currentStep.nextActive = nextStep.preActive = allActive
  }
})

const stepStyle = (index: number) => {
  const style: CSSProperties = {}
  const steps = props.steps
  const { length } = steps
  let width: string | number = 0
  if (length === 1) {
    width = '100%'
  }
  if (length === 2) {
    width = '50%'
  }
  if (length > 2) {
    const splited = 100 / ((length - 2) * 2 + 2)
    if (index === 0 || index === length - 1) {
      width = `${splited}%`
    } else {
      width = `${splited * 2}%`
    }
  }
  style.width = width
  if (!props.hasMultiple) {
    style.transform = 'translate(0, -30%)'
  }
  return style
}
</script>

<style lang="scss" scoped>
.steps {
  height: calc(100% - 16px - 10px);
  padding: 0 30px;
  display: flex;
  align-items: center;
  .step {
    height: 100%;
    position: relative;
    &-line {
      height: 6px;
      position: absolute;
      width: 50%;
      top: 50%;
      transform: translate(0, -50%);
      z-index: 1;
      &-before {
        left: 0;
      }
      &-after {
        right: 0;
      }
      &-active {
        background: #d5327b;
      }
      &-inactive {
        background: #b7b1b4;
      }
    }
    &:first-child,
    &:last-child {
      .step-line {
        width: 100%;
      }
    }
    &-state {
      position: absolute;
      width: 24px;
      height: 24px;
      background: #ffffff;
      border: 2px solid;
      border-radius: 50%;
      z-index: 2;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      .step-state-icon {
        width: 14px;
        height: 14px;
        border-radius: 50%;
        position: absolute;
        top: 50%;
        left: 50%;
        margin-top: -7px;
        margin-left: -7px;
      }
      &-active {
        border-color: #d5327b;
        .step-state-icon {
          background-color: #d5327b;
        }
      }
      &-inactive {
        border-color: #b7b1b4;
        .step-state-icon {
          background-color: #b7b1b4;
        }
      }
    }
    &-info {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, 24px);
      text-align: center;
      &-name {
        font-size: 14px;
        font-family: Microsoft YaHei;
        font-weight: bold;
        color: #101116;
      }
      &-desc {
        display: flex;
        flex-direction: column;
        &-item {
          height: 22px;
          line-height: 22px;
          font-family: DIN, Microsoft YaHei;
          font-weight: 400;
          color: #101116;
        }
      }
    }

    &:first-child:not(.sub-step) {
      .step-state,
      .step-info {
        left: 0;
      }
    }
    &:last-child:not(.sub-step) {
      .step-state {
        left: unset;
        right: 0;
        transform: translate(50%, -50%);
      }
      .step-info {
        left: unset;
        right: 0;
        transform: translate(50%, 24px);
      }
    }

    &.sub-step {
      margin: 0 auto;
      width: 80%;
      height: 50%;
      z-index: 2;
      background-color: #fff;
      &.sub-step-active {
        z-index: 11;
      }
      &.sub-step-inactive {
        z-index: 10;
      }
      .step-line::after {
        content: '';
        display: block;
        width: 6px;
        height: 20px;
        position: absolute;
      }
      .step-line-active::after {
        background-color: #d5327b;
      }
      .step-line-inactive::after {
        background-color: #b7b1b4;
      }
      .step-line-before::after {
        left: 0;
      }
      .step-line-after::after {
        right: 0;
      }
      &.sub-step-up {
        .step-line {
          top: unset;
          bottom: 20px;
          transform: translate(0, 50%);
          border-radius: 6px 6px 0 0;
          &::after {
            bottom: 0;
            transform: translate(0, 100%);
          }
        }
        .step-state {
          top: unset;
          bottom: 20px;
          transform: translate(-50%, 50%);
        }
        .step-info {
          top: 0;
          bottom: unset;
          transform: translate(-50%, 0);
        }
      }
      &.sub-step-down {
        .step-line {
          top: 20px;
          border-radius: 0 0 6px 6px;
          &::after {
            top: 0;
            transform: translate(0, -100%);
          }
        }
        .step-state {
          top: 20px;
        }
        .step-info {
          transform: translate(-50%, -20px);
        }
      }
    }
  }
}
</style>
