<template>
  <div class="jobs-wrap">
    <div class="jobs-wrap-txt" @click="show = true">
      <input type="text" disabled :value="selectedTexts[2]" :placeholder="placeholder" />
      <svg-icon icon-class="triangle-right" slot="button" />
    </div>
    <cr-popup v-model="show" get-container="body" round closeable position="bottom" class="jobs">
      <div class="jobs-head">
        <div class="jobs-title">请选择职业</div>
        <cr-divider :hairline="false" :style="{ color: '#F4F4F4', margin: 0 }" />
      </div>
      <!-- content -->
      <div class="jobs-content">
        <div class="job-list">
          <div
            class="jobs-item"
            v-for="(item, index) in industry"
            :key="index"
            :class="{ active: columns[0].values.length > 0 && index === columns[0].selectedIndex }"
            @click.stop="changeIndustry(item, index)"
          >
            <div class="jobs-item-txt">
              <span>{{ item.text }}</span>
              <cr-icon type="arrow" />
            </div>
            <div
              class="jobs-children"
              v-if="columns[0].values.length > 0 && index === columns[0].selectedIndex"
            >
              <div
                class="jobs-item"
                v-for="(it, idx) in columns[1].values"
                :class="{
                  active: columns[1].values.length > 0 && idx === columns[1].selectedIndex
                }"
                :key="idx"
                @click.stop="changeCategory(it, idx)"
              >
                <div class="jobs-item-txt">
                  <span>{{ it.text }}</span>
                  <cr-icon type="arrow" />
                </div>
                <div
                  class="jobs-children jobs-leaf"
                  v-if="columns[2].values.length > 0 && idx === columns[1].selectedIndex"
                >
                  <div
                    class="jobs-item"
                    v-for="(itc, idxc) in columns[2].values"
                    :key="idxc"
                    @click.stop="changeProfession(itc, idxc)"
                  >
                    <div class="jobs-item-txt">{{ itc.text }}</div>
                  </div>
                </div>
                <cr-divider />
              </div>
            </div>
            <cr-divider />
          </div>
        </div>
      </div>
    </cr-popup>
  </div>
</template>

<script>
// TODO 组件目前只针对职业码表处理，有待优化
/**
 * @description: 职业码表
 * @param {type}
 * @return:
 */
import popupPickerMixin from "../mixins/popupPicker.mixin.js";
import jobs from "@/api/jobs";
const CHANGE_EVENT = "input";
const INDUSTRY_INDEX = 0;
const CATEGORY_INDEX = 1;
const PROFESSION_INDEX = 2;
export default {
  name: "PopupCascade",
  mixins: [popupPickerMixin],
  props: {
    value: null,
    isLite: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    value(val) {
      if (val) {
        const value = "" + val;
        this.selectedCodes = [value.substring(0, 1), value.substring(0, 3), value];
        this.renderIndustry();
      }
    },
    popupShow(val) {
      this.$emit(CHANGE_EVENT, val);
    }
  },
  computed: {
    industry() {
      const list = this.jobs[this.industryKey];
      return Object.keys(list).map(key => {
        return {
          code: key,
          text: list[key]
        };
      });
    },
    category() {
      const list = this.jobs[this.categoryKey];
      return Object.keys(list).map(key => {
        return {
          code: key,
          text: list[key]
        };
      });
    },
    profession() {
      const key = this.isLite ? this.professionLiteKey : this.professionKey;
      const list = this.jobs[key];
      return Object.keys(list).map(key => {
        return {
          code: key,
          text: list[key]
        };
      });
    }
  },
  data() {
    return {
      show: false,
      jobs,
      industryKey: "industry",
      categoryKey: "category",
      professionKey: "profession",
      professionLiteKey: "professionLite",
      columns: [],
      selectedCodes: [],
      selectedTexts: []
    };
  },
  created() {
    if (this.value) {
      const value = "" + this.value;
      this.selectedCodes = [value.substring(0, 1), value.substring(0, 3), value];
    }

    for (let i = 0; i < 3; i++) {
      this.columns[i] = {
        values: [],
        selectedIndex: ""
      };
    }
  },
  mounted() {
    this.renderIndustry();
  },
  methods: {
    changeIndustry(item, index) {
      if (index === this.columns[INDUSTRY_INDEX].selectedIndex) {
        this.columns[INDUSTRY_INDEX].selectedIndex = "";
        this.$forceUpdate();
      } else {
        this.columns[INDUSTRY_INDEX].selectedIndex = index;
        this.setValueOfSelected(item, INDUSTRY_INDEX);
        this.renderCategory(item.code);
      }
      this.columns[CATEGORY_INDEX].selectedIndex = "";
      this.columns[PROFESSION_INDEX].selectedIndex = "";
    },
    changeCategory(item, index) {
      if (index === this.columns[CATEGORY_INDEX].selectedIndex) {
        this.columns[CATEGORY_INDEX].selectedIndex = "";
        this.$forceUpdate();
        return;
      } else {
        this.columns[CATEGORY_INDEX].selectedIndex = index;
        this.setValueOfSelected(item, CATEGORY_INDEX);
        this.renderProfession(item.code);
      }
      this.columns[PROFESSION_INDEX].selectedIndex = "";
    },
    changeProfession(item, index) {
      this.columns[PROFESSION_INDEX].selectedIndex = index;
      this.setValueOfSelected(item, PROFESSION_INDEX);
      this.$emit(CHANGE_EVENT, item.code);
      this.show = false;
    },
    renderIndustry() {
      this.columns[INDUSTRY_INDEX].values = this.industry;
      this.setDefaultIndexOfColumn(this.industry, INDUSTRY_INDEX);
      const industry = this.industry[this.columns[INDUSTRY_INDEX].selectedIndex];
      if (industry) {
        this.setValueOfSelected(industry, INDUSTRY_INDEX);
        this.renderCategory(industry?.code);
      }
    },
    renderCategory(industryCode) {
      const categoryOfIndustry = this.quickFilter(this.category, 1, industryCode);
      this.columns[CATEGORY_INDEX].values = categoryOfIndustry;
      this.setDefaultIndexOfColumn(categoryOfIndustry, CATEGORY_INDEX);
      const category = categoryOfIndustry[this.columns[CATEGORY_INDEX].selectedIndex];
      if (category) {
        this.setValueOfSelected(category, CATEGORY_INDEX);
        this.renderProfession(category?.code);
      }
      this.$forceUpdate();
    },
    renderProfession(categoryCode) {
      const professionOfCategory = this.quickFilter(this.profession, 3, categoryCode);
      this.columns[PROFESSION_INDEX].values = professionOfCategory;
      this.setDefaultIndexOfColumn(professionOfCategory, PROFESSION_INDEX);
      const profession = professionOfCategory[this.columns[PROFESSION_INDEX].selectedIndex];
      if (profession) {
        this.setValueOfSelected(profession, PROFESSION_INDEX);
      }
      this.$forceUpdate();
    },
    quickFilter(list, slice, code) {
      const prefix = code.substring(0, slice);
      let start = false;
      const filtered = [];
      for (let i = 0, len = list.length; i < len; i++) {
        if (list[i].code.substr(0, slice) === prefix) {
          start = true;
          filtered.push(list[i]);
        } else {
          if (start) {
            break;
          }
        }
      }
      return filtered;
    },
    setValueOfSelected(item, index) {
      this.selectedCodes[index] = item.code;
      this.selectedTexts[index] = item.text;
    },
    setDefaultIndexOfColumn(list, index) {
      if (this.selectedCodes[index]) {
        list.some((item, i) => {
          if (item.code === this.selectedCodes[index]) {
            this.columns[index].selectedIndex = i;
            return true;
          }
          return false;
        });
        // clear after first render
        this.selectedCodes[index] = "";
      }
    }
  }
};
</script>

<style lang="less" scoped>
@import "../style/var.less";
.body-wrap-mixin {
  overflow-x: hidden;
  overflow-y: auto;
  height: calc(70vh - 90px);
  padding: @padding-lg;
}
.jobs {
  z-index: 200;
  height: 70vh;
  overflow: hidden;
  @{deep} .cr-icon {
    position: absolute;
    color: #d0cfcf;
    font-size: @font-size-18;
    top: 16px;
    right: 14px;
    z-index: 201;
  }
  &-wrap {
    width: 100%;
    &-txt {
      height: 24px;
      color: #333;
      font-size: 14px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      input {
        width: 90%;
        &:disabled {
          background-color: transparent;
        }
      }
    }
  }
  &-head {
    width: 100%;
  }
  &-title {
    font-weight: @font-weight-bold;
    font-size: @font-size-18;
    color: @black;
    line-height: @line-height-lg + 1;
    padding: 13px 0 10px;
    text-align: center;
  }
  &-content {
    .body-wrap-mixin();
    font-size: @font-size-12;
    color: @gray-5;
    line-height: @line-height-md - 2;
  }
  &-list {
    width: 100%;
  }
  &-item {
    .cr-divider {
      margin: 0;
    }
    &-txt {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-size: 15px;
      color: #333;
      padding: 12px 0;
      .cr-icon {
        font-size: 14px;
        color: #333;
        position: initial;
        transition: tranform 0.2s linear;
      }
    }
    &.active {
      & > .jobs-item-txt > .cr-icon {
        transform: rotate(90deg);
      }
    }
    &:last-child {
      .cr-divider {
        display: none;
      }
    }
  }
  &-children {
    padding: 2px 0 2px 10px;
    &.jobs-leaf {
      border-radius: 8px;
      background-color: @gray-1;
      .jobs-item-txt {
        margin: 10px 0;
      }
    }
    .jobs-item-txt {
      color: @gray-5;
      padding: 0;
      margin: 8px 0;
      font-size: 14px;
    }
  }
}
</style>
