<template>
  <el-popover
    v-model="popup"
    placement="bottom-start"
    popper-class="address-popover"
    trigger="click"
    :width="popoverWidth">
    <div class="address-popover__content">
      <el-tabs v-model="curLevel">
        <el-tab-pane
          v-for="(id, level) in selectCodeList"
          :key="level"
          :label="getLabelByLevel(level)"
          :name="level + ''"
        >
          <ul class="address__list">
            <li
              v-for="item in getRegionListByLevel(level)"
              :class="getAddressItemClass(item)"
              :key="item.name"
              class="address__item"
              @click="handleSelect(level, item)"
            >
              {{item.name}}
            </li>
          </ul>
        </el-tab-pane>
      </el-tabs>
    </div>
    <el-input
      ref="input"
      slot="reference"
      v-model="finalLabel"
      :width="width"
      :placeholder="placeholder"
      :disabled="disabled"
      :prefix-icon="prefixIcon"
      :suffix-icion="suffixIcon"
      :autosize="autosize"
      :name="name"
      :label="label"
      :readonly="true"/>
  </el-popover>
</template>
<script>
/**
 * Created by fuzl on 2017-12-27.
 */
import loadTool from '../utils/loadscript';

const ROOT_CODE = '000000';

export default {
  name: 'SyAddress',
  props: ['value', 'width', 'placeholder', 'disabled', 'prefixIcon', 'suffixIcon', 'autosize', 'name', 'label'],
  data() {
    return {
      popup: false,
      curLevel: '0',
      finalLabel: '',
      popoverWidth: 360,
      selectedItem: null,
      // 地区字符小于等于6使用小长度
      smallSizeLength: 5,
      selectLabelList: [],
      selectCodeList: [''],
      regions: [{}, {}, {}],
    };
  },
  methods: {
    /**
     * @return {boolean|undefined} - 当选择完最后一项时，返回true，否则返回undefined
     * */
    // eslint-disable-next-line consistent-return
    handleSelect(level, item) {
      const curLevel = Number(level);
      this.selectLabelList = this.selectLabelList.slice(0, curLevel).concat(item.name);
      this.selectCodeList = this.selectCodeList.slice(0, curLevel).concat(item.id);
      if (curLevel === this.regions.length - 1 || !this.hasChildren(curLevel, item)) {
        this.popup = false;
        this.selectedItem = item;
        this.emitValue();
        this.finalLabel = this.selectLabelList.join('-');
        return true;
      }
      this.curLevel = `${curLevel + 1}`;
      this.selectCodeList.push('');
    },
    /**
     * @description 该区域下是否还有子区域，有些区域等级不足三级
     * */
    hasChildren(level, item) {
      const curLevel = Number(level);
      const nextRegion = this.regions[curLevel + 1];
      return nextRegion ? nextRegion[item.id] !== undefined : false;
    },
    getAddressItemClass(item) {
      if (item.name.length > this.smallSizeLength) {
        return 'address__item--long';
      }
      return '';
    },
    getRegionListByLevel(level) {
      let pCode;
      if (level === 0) {
        pCode = ROOT_CODE;
      } else {
        pCode = this.selectCodeList[level - 1];
      }
      return this.regions[level][pCode] || [];
    },
    getLabelByLevel(level) {
      return this.selectLabelList[level] || '请选择';
    },
    emitValue() {
      this.$emit('input', typeof this.value === 'string' ? this.selectedItem.id : this.selectedItem);
    },
    setValue() {
      const value = this.getValueFromProp();
      // 相同的value，不做更新
      if (this.selectedItem && value === this.selectedItem.id) {
        return;
      }
      if (value) {
        let i = 0;
        const unitLength = 2;
        const fillStr = '00';
        const unitCount = this.regions.length;
        // fucking 三段式两两字符分割，补全0，脆弱的设计
        while (i < unitCount) {
          i += 1;
          const level = this.curLevel;
          const id = value.slice(0, unitLength * i) + this.repeatString(fillStr, unitCount - i);
          const list = this.getRegionListByLevel(level);
          const result = list.filter((item) => item.id === id)[0];
          // 匹配到结果
          if (result) {
            this.handleSelect(level, result);
            // 类似香港等地区，没有区县，提前结束
            if (!this.hasChildren(level, result)) {
              break;
            }
          }
        }
        this.finalLabel = this.selectLabelList.join('-');
      } else {
        // value为空，需要清除选中项
        this.clearSelected();
      }
    },
    getValueFromProp() {
      let { value } = this;
      if (value && typeof value === 'object') {
        value = value.id;
      }
      return value || '';
    },
    clearSelected() {
      this.curLevel = '0';
      this.selectedItem = null;
      this.selectLabelList = [];
      this.selectCodeList = [''];
    },
    repeatString(str, repeatTimes) {
      let i = 0;
      let result = '';
      while (i < repeatTimes) {
        i += 1;
        result += str;
      }
      return result;
    },
  },
  watch: {
    value(val) {
      this.setValue(val);
    },
  },
  created() {
    loadTool.loadAllRegionData().then((regions) => {
      this.regions = regions;
      this.setValue();
    });
  },
  mounted() {
    this.popoverWidth = this.$refs.input.$el.offsetWidth || 360;
  },
};
</script>
<style></style>
