<template>
  <div class="steps" v-if="$parent.simple">
    <div class="step-item" :class="[$parent.active === index ? 'active' : '']">
      <slot name="title"> {{ title }} </slot>
    </div>
    <span class="triangle" :class="[$parent.active === index ? 'triangle-active' : '', $parent.active == index + 1 ? 'triangle-bg' : 'triangle-default']"></span>
  </div>
  <div v-else class="dm-step" :style="style" :class="[isLast && !space && 'is-flex']">
    <div class="dm-step-box" :class="`is-${currentStatus}`">
      <!-- 线 -->
      <div class="dm-step__line" :style="isLast ? '' : { marginRight: $parent.stepOffset + 'px' }">
        <i class="dm-step__line-inner" :style="lineStyle"></i>
      </div>

      <div class="dm-step__head">
        <!-- icon -->
        <div class="dm-step__icon">
          <slot v-if="currentStatus !== 'success' && currentStatus !== 'error'" name="icon">
            <i v-if="icon" class="dm-step__icon-inner" :class="[icon]"></i>
            <div class="dm-step__icon-inner" v-if="!icon">{{ index + 1 }}</div>
          </slot>
          <i v-else :class="['el-icon-' + (currentStatus === 'success' ? 'check' : 'close')]" class="dm-step__icon-inner is-status"> </i>
        </div>

        <!-- 内容区 -->
        <div class="dm-step__content" :class="`is-${currentStatus}`">
          <slot name="title">{{ title }}</slot>
        </div>
      </div>
    </div>

    <!-- 文字描述 -->
    <div class="dm-step__description" :class="`is-${currentStatus}`">
      <slot name="description">{{ description }}</slot>
    </div>
  </div>
</template>

<script>
export default {
  name: 'vue-gic-step',

  props: {
    title: String,
    icon: String,
    description: String,
    status: String
  },
  data() {
    return {
      index: -1,
      lineStyle: {},
      internalStatus: ''
    };
  },

  beforeCreate() {
    this.$parent.steps.push(this);
  },

  beforeDestroy() {
    const steps = this.$parent.steps;
    const index = steps.indexOf(this);
    if (index >= 0) {
      steps.splice(index, 1);
    }
  },

  computed: {
    currentStatus() {
      return this.status || this.internalStatus;
    },
    prevStatus() {
      const prevStep = this.$parent.steps[this.index - 1];
      return prevStep ? prevStep.currentStatus : 'wait';
    },
    isLast() {
      const parent = this.$parent;
      return parent.steps[parent.steps.length - 1] === this;
    },
    space() {
      const {
        $parent: { space }
      } = this;
      return space;
    },
    style: function() {
      const style = {};
      const parent = this.$parent;
      const len = parent.steps.length;

      const space = typeof this.space === 'number' ? this.space + 'px' : this.space ? this.space : 100 / (len - 1) + '%';
      style.flexBasis = space;
      return style;
    }
  },

  methods: {
    updateStatus(val) {
      const prevChild = this.$parent.$children[this.index - 1];

      if (val > this.index) {
        this.internalStatus = this.$parent.finishStatus;
      } else if (val === this.index && this.prevStatus !== 'error') {
        this.internalStatus = this.$parent.processStatus;
      } else {
        this.internalStatus = 'wait';
      }

      if (prevChild) prevChild.calcProgress(this.internalStatus);
    },

    calcProgress(status) {
      let step = 100;
      const style = {};

      style.transitionDelay = 150 * this.index + 'ms';
      if (status === 'wait') {
        step = 0;
        style.transitionDelay = -150 * this.index + 'ms';
      }

      style.borderWidth = step ? '1px' : 0;
      style.width = step + '%';

      this.lineStyle = style;
    }
  },

  mounted() {
    const unwatch = this.$watch('index', val => {
      this.$watch('$parent.active', this.updateStatus, { immediate: true });
      this.$watch(
        '$parent.processStatus',
        () => {
          const activeIndex = this.$parent.active;
          this.updateStatus(activeIndex);
        },
        { immediate: true }
      );
      unwatch();
    });
  }
};
</script>

<style lang="scss">
.dm-step {
  position: relative;
  flex-shrink: 1;
  &:last-of-type.is-flex {
    flex-basis: 80px !important;
    flex-shrink: 1;
    flex-grow: 0;
    .dm-step__content {
      flex: 1;
    }
  }

  .dm-step-box {
    position: relative;
    width: 100%;
    &.is-process {
      color: #fff;
      border-color: #2f54eb;
      .dm-step__icon {
        background-color: #2f54eb;
      }
    }
    &.is-finish,
    &.is-success {
      color: #2f54eb;
      border-color: #2f54eb;
    }
    &.is-wait {
      color: #c0c4cc;
      border-color: #c0c4cc;
    }
  }

  .dm-step__line {
    position: absolute;
    height: 1px;
    top: 11px;
    left: 0;
    right: 0;
    border-color: inherit;
    background-color: #dcdfe6;
  }
  .dm-step__line-inner {
    display: block;
    border-top: 1px solid;
    border-color: inherit;
    transition: 0.15s ease-out;
    box-sizing: border-box;
    width: 0;
    height: 0;
  }

  .dm-step__head {
    display: flex;
    width: 100%;
    border-color: inherit;
  }
  .dm-step__icon {
    position: relative;
    z-index: 1;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    width: 24px;
    height: 24px;
    font-size: 14px;
    box-sizing: border-box;
    background-color: #fff;
    transition: 0.15s ease-out;
    border-radius: 50%;
    border: 1px solid;
    border-color: inherit;

    &-inner {
      display: inline-block;
      user-select: none;
      text-align: center;
      line-height: 1;
      color: inherit;
      &.is-status {
        font-size: 16px;
        transform: translateY(1px);
      }
    }
  }

  .dm-step__content {
    position: relative;
    z-index: 2;
    line-height: 25px;
    padding-left: 8px;
    padding-right: 18px;
    background-color: #fff;
    font-size: 16px;
    &.is-process {
      color: #303133;
      font-weight: 500;
    }
    &.is-finish,
    &.is-success {
      color: #303133;
    }
    &.is-wait {
      color: #909399;
    }
  }

  .dm-step__description {
    padding-left: 32px;
    line-height: 24px;
    color: #909399;
    &.is-process {
      color: #606266;
    }
  }
}
.steps {
  display: flex;
  width: 100%;
  position: relative;
  // margin-right: 10px;
  .active {
    background: #2f54eb;
    color: #fff;
  }
}
.step-item {
  flex: 1;
  background: #eef4ff;
  color: #303133;
  height: 44px;
  text-align: center;
  line-height: 44px;
  cursor: pointer;
  font-size: 14px;
}
.triangle {
  width: 0;
  height: 0;
  display: inline-block;
  z-index: 2;
  border-style: solid;
  border-width: 22px 0 22px 12px;
  position: relative;
  background: #eef4ff;
  border-color: transparent transparent transparent #eef4ff;
}
.steps:last-of-type {
  .triangle {
    background: #fff;
  }
}
.triangle::before {
  content: '';
  position: absolute;
  height: 28px;
  width: 4px;
  background: #fff;
  transform: rotate(-209deg) translateY(-0.7px);
  transform-origin: 0 0;
  top: 0;
  right: -6px;
}
.triangle::after {
  content: '';
  bottom: 0;
  position: absolute;
  height: 27px;
  width: 4px;
  background: #fff;
  transform: rotate(209deg) translateY(1.3px);
  transform-origin: 100% 100%;
  right: 1.8px;
}
.triangle-active {
  border-left-color: #2f54eb;
}
.triangle-bg {
  background: #2f54eb;
}
.triangle-default {
  background: #eef4ff;
}
</style>
