<template>
  <div
    :style="!isSimple?style:''"
    :class="[
      !isSimple?'el-step':'el-simple',
      !isSimple?!isSimple && `is-${$parent.direction}`:'',
      !isSimple?isSimple && 'is-simple':'',
      !isSimple?isLast && !space && !isCenter && 'is-flex':'',
      !isSimple?isCenter && !isVertical && !isSimple && 'is-center':''
     ]"
     >
    <!-- icon & line -->
    <div
      class="el-step__head"
      v-if="!isSimple"
      :class="`is-${currentStatus}`">
      <div
        class="el-step__line"
        :style="isLast ? '' : { marginRight: $parent.stepOffset + 'px' }"
      >
        <i class="el-step__line-inner" :style="lineStyle"></i>
      </div>

      <div class="el-step__icon is-text">
        <slot
          v-if="currentStatus !== 'success' && currentStatus !== 'error'"
          name="icon">
          <!-- <i v-if="icon" class="el-step__icon-inner" :class="[icon]"></i> -->
          <div class="el-step__icon-inner is-status" v-if="!isSimple"></div>
        </slot>
        <!-- <i v-else class="el-step__icon-inner is-status"></i> -->
      </div>
    </div>
    <!-- title & description -->
    <div class="el-step__main" v-if="!isSimple">
      <div
        class="el-step__title"
        ref="title"
        :class="['is-' + currentStatus]">
        <slot name="title">{{ title }}</slot>
      </div>
      <div v-if="isSimple" class="el-step__arrow"></div>
      <div
        v-else
        class="el-step__description"
        :class="['is-' + currentStatus]">
        <slot name="description">{{ description }}</slot>
      </div>
    </div>
    <!-- simple -->
    <div class="ce-step-container" :style="containerStyle" v-if="isSimple">
      <div
        v-if="!isFirst"
        class="ce-step-arrow"
        :style="stepWhiteArrowStyle"
      />
      <div class="ce-step borderBox flex fontSize12" :style="stepStyle">
        <slot name="icon">
          <i :class="icon" class="el-step__icon-simple"/>
        </slot>
        <div
          class="ce-step-title borderBox"
          :style="ceStatus === 'wait' || ceActiveStatus === 'wait' ? 'color: rgba(0,16,47,0.65);' : ''"
        >
          {{ title }}
        </div>
      </div>
      <div v-if="!isLast" class="ce-step-arrow" :style="stepArrowStyle" />
    </div>
  </div>
</template>

<script>
export default {
  name: 'ElStep',

  props: {
    title: String,
    icon: String,
    description: String,
    status: String,
    isLastStep: {
      type: Boolean
    },
    isFirstStep: {
      type: Boolean
    },
    ceStatus: {
      type: String
    },
    height: {
      type: Number,
      default: 32
    }
  },

  data() {
    return {
      index: -1,
      lineStyle: {},
      internalStatus: '',
      ceActiveStatus: '',
      bgColor: {
        process: '#596378',
        wait: '#D9DBE0',
        success: '#6FC77E',
        error: '#F95F5B'
      }
    };
  },

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

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

  updated() {
    this.$parent.$emit('step-slot-update');
  },
  computed: {
    currentStatus() {
      return this.status || this.internalStatus;
    },
    prevStatus() {
      const prevStep = this.$parent.steps[this.index - 1];
      return prevStep ? prevStep.currentStatus : 'wait';
    },
    isCenter() {
      return this.$parent.alignCenter;
    },
    isVertical() {
      return this.$parent.direction === 'vertical';
    },
    isSimple() {
      return this.$parent.simple;
    },
    isLast() {
      const parent = this.$parent;
      return parent.steps[parent.steps.length - 1] === this;
    },
    isFirst() {
      const parent = this.$parent;
      return parent.steps[0] === this;
    },
    stepsCount() {
      return this.$parent.steps.length;
    },
    space() {
      const { isSimple, $parent: { space } } = this;
      return isSimple ? '' : 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 - (this.isCenter ? 0 : 1)) + '%');
      style.flexBasis = space;
      if (this.isVertical) return style;
      if (this.isLast) {
        style.maxWidth = 100 / this.stepsCount + '%';
      } else {
        style.marginRight = -this.$parent.stepOffset + 'px';
      }

      return style;
    },
    containerStyle() {
      const marginRight = 3;

      return 'width:calc(' + 100 + '% - ' + marginRight + 'px)';
    },
    stepStyle() {
      // 'width:' + (100 / this.stepNum) + '%;' //'width: calc(25% - 4px)' //`width:calc(${100 / this.stepNum}% - ${marginRight}px);`
      const sizeStr = 'height:' + this.height + 'px;';
      const backgroundStr = 'background:' + this.stepColor + ';';
      const lineHeightStr = 'line-height:' + this.height + 'px;';
      const paddingLeftNum = this.isFirst ? 8 : +this.height / 2 + 8;
      const paddingStr = 'padding-left:' + paddingLeftNum + 'px;';

      return sizeStr + backgroundStr + lineHeightStr + paddingStr;
    },
    stepColor() {
      // 设置stepColor颜色
      if (this.$parent.active === 0 || this.$parent.active) {
        if (this.index === this.$parent.active) {
          this.ceActiveStatus = this.$parent.processStatus ? this.$parent.processStatus : 'process';
        } else if (this.index < this.$parent.active) {
          if (this.$parent.finishStatus) {
            this.ceActiveStatus = this.$parent.finishStatus;
            if (this.$parent.finishStatus === 'finish') this.ceActiveStatus = 'success';
          } else if (this.$parent.processStatus) {
            this.ceActiveStatus = this.$parent.processStatus;
          } else {
            this.ceActiveStatus = 'success';
          };
        } else {
          this.ceActiveStatus = 'wait';
        }
        return this.bgColor[this.ceActiveStatus];
      } else {
        return this.bgColor[this.ceStatus];
      }
    },
    stepArrowStyle() {
      const borderStr = 'border:' + (this.height / 2) + 'px solid transparent; border-left-color:' + this.stepColor + ';';
      const posStr = 'right:' + (this.height / -1) + 'px;';

      return borderStr + posStr;
    },
    stepWhiteArrowStyle() {
      const borderStr = 'border:' + (this.height / 2) + 'px solid transparent; border-left-color: #fff;';
      const posStr = 'left: 0;z-index: 1';

      return borderStr + posStr;
    }
  },

  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 === this.$parent.processStatus) {
        step = this.currentStatus !== 'error' ? 0 : 0;
      } else if (status === 'wait') {
        step = 0;
        style.transitionDelay = (-150 * this.index) + 'ms';
      }

      style.borderWidth = step && !this.isSimple ? '1px' : 0;
      this.$parent.direction === 'vertical'
        ? style.height = step + '%'
        : 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>
