<template>
  <div class="aos-city">
    <el-cascader
      v-model="cityData"
      v-show="edit"
      :options="provinceOptions"
      @expand-change="handleItemChange"
      @change="handleChange"
      @focus="handleFocus"
      :separator="separator"
      :placehold="placeholder"
      :disabled="disabled"
      :clearable="clearable"
      :props="cityProps"
      popper-class="aos-select-car-cascader-popper"
    ></el-cascader>
    <div v-show="!edit" class="el-form-item__content aos-form-input-text">
      <div :title="realValue">
        {{realValue}}
      </div>
    </div>
  </div>
</template>
<script>
import cloneDeep from 'lodash/cloneDeep'
import debounce from 'throttle-debounce/debounce';
export default {
  name: 'AosCity',
  props: {
    // 编辑状态
    edit: {
      type: Boolean,
      default: true
    },
    // 省
    province: {
      type: String,
      default: '',
      required: true
    },
    // 市
    city: {
      type: String,
      default: '',
      required: true
    },
    // 县
    county: {
      type: String,
      default: '',
      required: false
    },
    //
    templateValue: {
      type: Object,
      required: true
    },
    // 禁用状态
    disabled: {
      type: Boolean,
      default: false
    },
    // 提示
    placeholder: {
      type: String,
      default: '请选择省/市/县'
    },
    // 选项分隔符
    separator: {
      type: String,
      default: '/'
    },
    clearable: {
      type: Boolean,
      default: false
    },
    // 自定义外部请求接口
    customerUrl: {
      type: String,
      default: '/core/api/area-info/ref'
    },
    customerMethod: {
      type: String,
      default: 'post'
    }
  },
  data() {
    return {
      provinceOptions: [],
      cityProps: {
        label: 'value',
        value: 'code',
        children: 'citys'
      },
      cityData: [],
      realValue: '',
      cityOptions: [],
      countyOptions: [],
      debounceInit: '',
      debounceSetCityData: '',
    };
  },
  created() {
    this.debounceInit = debounce(10, this.init)
    this.debounceSetCityData = debounce(10, this.setCityData)
    this.debounceSetCityData();
    this.debounceInit();
  },
  methods: {
    setCityData () {
      if (this.province && this.city && this.county) {
        this.cityData.splice(0)
        this.cityData.push(this.templateProvince)
        this.cityData.push(this.templateCity)
        this.cityData.push(this.templateCounty)
      } else if (this.province && this.city) {
        this.cityData.splice(0)
        this.cityData.push(this.templateProvince)
        this.cityData.push(this.templateCity)
      } else if (this.province) {
        this.cityData.splice(0)
        this.cityData.push(this.templateProvince)
      }
    },
    async handleItemChange(val) {
      if (val.length === 1) {
        await this.getCity('', val[0]);
        if (this.city) {
          await this.setProvinceChildrenCity(val[0]);
        }
      } else if (val.length === 2) {
        await this.getCounty('', val[1]);
        if (this.county) {
          await this.setCityChildrenCounty(val);
        }
      } else if (val.length === 3) {
        if (!val[1]) {
          await this.getCity('', val[0]);
          if (this.city) {
            await this.setProvinceChildrenCity(val[0]);
          }
        } else if (!val[2]) {
          await this.getCounty('', val[1]);
          if (this.county) {
            await this.setCityChildrenCounty(val);
          }
        }
      }
    },
    getProvince(query) {
      if (!query) {
        query = '';
      }
      let params = {
        query: query,
        parentId: ''
      };
      return this.$optimizeHttp({
        url: this.copyCustomerUrl,
        method: this.copyCustomerMethod,
        params: params
      }).then((res) => {
        this.provinceOptions = cloneDeep(res.data);
        return res.data
      }).catch(() => {
        this.$message({
          typr: 'error',
          message: '请求省份信息出错'
        });
      });
    },
    setProvinceChildren () {
      if (this.provinceOptions && this.provinceOptions.length > 0) {
        this.provinceOptions.forEach((item) => {
          if (!item.citys) {
            this.$set(item, 'citys', []);
          }
        });
      }
      return Promise.resolve();
    },
    getCity(query, val) {
      let params = {
        query: query,
        parentId: val
      };
      return this.$optimizeHttp({
        url: this.copyCustomerUrl,
        method: this.copyCustomerMethod,
        params: params
      }).then((res) => {
        this.cityOptions = cloneDeep(res.data);
        return res.data
      }).catch(() => {
        this.$message({
          typr: 'error',
          message: '请求市级信息出错'
        });
      });
    },
    setProvinceChildrenCity (val) {
      if (this.county) {
        this.cityOptions.forEach((item) => {
          this.$set(item, 'citys', []);
        });
      }
      for (let i = 0;i < this.provinceOptions.length;i++) {
        if (val === this.provinceOptions[i].code) {
          this.provinceOptions[i].citys = cloneDeep(this.cityOptions)
          break;
        }
      }
      return Promise.resolve()
    },
    getCounty(query, val) {
      let params = {
        query: query,
        parentId: val
      };
      return this.$optimizeHttp({
        url: this.copyCustomerUrl,
        method: this.copyCustomerMethod,
        params: params
      }).then((res) => {
        this.countyOptions = cloneDeep(res.data);
        return res.data
      }).catch(() => {
        this.$message({
          typr: 'error',
          message: '请求市级信息出错'
        });
      });
    },
    setCityChildrenCounty (val) {
      let countyOptions = cloneDeep(this.countyOptions)
      let cityOption = [];
      for (let i = 0;i < this.provinceOptions.length;i++) {
        if (val[0] === this.provinceOptions[i].code) {
          cityOption = this.provinceOptions[i].citys;
          break;
        }
      }
      for (let i = 0;i < cityOption.length;i++) {
        if (val[1] === cityOption[i].code) {
          cityOption[i].citys = countyOptions;
          break;
        }
      }
      return Promise.resolve()
    },
    handleFocus(event) {
      this.$emit('focus', event);
    },
    handleChange(val) {
      this.setRealValue(val);
      this.setTemplateData(val)
      this.$emit('change', val);
    },
    setRealValue(val) {
      const provinceOptions = cloneDeep(this.provinceOptions)
      this.realValue = ''
      let cityOption = [];
      let countyOption = [];
      let changeValue = {};
      if (val[0]) {
        for (let i = 0;i < provinceOptions.length;i++) {
          if (val[0] === provinceOptions[i].code) {
            cityOption = provinceOptions[i].citys;
            changeValue.provinceName = provinceOptions[i].value;
            changeValue.provinceCode = provinceOptions[i].code;
            break;
          }
        }
      }
      if (val[1] && cityOption && Array.isArray(cityOption)) {
        for (let i = 0;i < cityOption.length;i++) {
          if (val[1] === cityOption[i].code) {
            countyOption = cityOption[i].citys;
            changeValue.cityName = cityOption[i].value;
            changeValue.cityCode = cityOption[i].code;
            break;
          }
        }
      }
      if (val[2] && countyOption && Array.isArray(countyOption)) {
        for (let i = 0;i < countyOption.length;i++) {
          if (val[2] === countyOption[i].code) {
            changeValue.countyName = countyOption[i].value;
            changeValue.countyCode = countyOption[i].code;
            break;
          }
        }
      }
      if (this.province && this.city && this.county && changeValue.provinceName && changeValue.cityName && changeValue.countyName) {
        this.realValue = changeValue.provinceName + '/' + changeValue.cityName + '/' + changeValue.countyName;
      } else if (this.province && this.city && changeValue.provinceName && changeValue.cityName) {
        this.realValue = changeValue.provinceName + '/' + changeValue.cityName 
      } else if (this.province && changeValue.provinceName) {
        this.realValue = changeValue.provinceName
      }
    },
    setTemplateData (val) {
      this.templateValue[this.province] = val[0];
      if (this.city) {
        this.templateValue[this.city] = val[1];
      }
      if (this.county) {
        this.templateValue[this.county] = val[2];
      }
    },
    async getProvinceLabel () {
      const self = this
      return new Promise(async (resolve, reject) => {
        this.provinceLabel = ''
        try {
          await self.getProvince()
          for (let i = 0;i < self.provinceOptions.length;i++) {
            if (self.templateProvince === self.provinceOptions[i].code) {
              self.provinceLabel = self.provinceOptions[i].value;
              break;
            }
          }
          resolve(this.provinceLabel)
        } catch (error) {
          reject()
          console.log(error)
        }
      })
    },
    async getCityLabel () {
      return new Promise(async (resolve, reject) => {
        this.cityLabel = ''
        try {
          await this.getCity('', this.templateProvince)
          for (let i = 0;i < this.cityOptions.length;i++) {
            if (this.templateCity === this.cityOptions[i].code) {
              this.cityLabel = this.cityOptions[i].value;
              break;
            }
          }
          resolve(this.cityLabel)
        } catch (error) {
          reject()
          console.log(error)
        }
      })
    },
    async getCountyLabel () {
      return new Promise(async (resolve, reject) => {
        this.countyLabel = ''
        try {
          await this.getCounty('', this.templateCity)
          for (let i = 0;i < this.countyOptions.length;i++) {
            if (this.templateCounty === this.countyOptions[i].code) {
              this.countyLabel = this.countyOptions[i].value;
              break;
            }
          }
          resolve(this.countyLabel)
        } catch (error) {
          reject()
          console.log(error)
        }
      })
    },
    async init () {
      if (this.templateProvince && this.templateCity && this.templateCounty) {
        try {
          await this.getProvinceLabel()
          await this.setProvinceChildren()
          await this.getCityLabel()
          await this.setProvinceChildrenCity(this.templateProvince)
          await this.getCountyLabel()
          await this.setCityChildrenCounty([this.templateProvince, this.templateCity])
          this.setRealValue([this.templateProvince, this.templateCity, this.templateCounty])
        } catch (error) {
        }
      } else if (this.templateProvince && this.templateCity) {
        try {
          await this.getProvinceLabel()
          await this.setProvinceChildren()
          await this.getCityLabel()
          await this.setProvinceChildrenCity(this.templateProvince)
          this.setRealValue([this.templateProvince, this.templateCity, ''])
        } catch (error) {
        }
      } else if (this.templateProvince) {
        try {
          await this.getProvinceLabel()
          await this.setProvinceChildren()
          this.setRealValue([this.templateProvince, '', ''])
        } catch (error) {
        }
      } else {
        try {
          await this.getProvince();
          await this.setProvinceChildren()
          this.setRealValue([this.templateProvince, this.templateCity, this.templateCounty])
        } catch (error) {
        }
      }
    },
  },
  computed: {
    templateProvince: function() {
      if (this.province) {
        return this.templateValue[this.province];
      }
    },
    templateCity: function() {
      if (this.city) {
        return this.templateValue[this.city];
      }
    },
    templateCounty: function() {
      if (this.county) {
        return this.templateValue[this.county];
      }
    },
    copyCustomerUrl: function () {
      let url = '/core/api/area-info/ref'
      if (this.customerUrl) {
        url = this.customerUrl
      }
      return url
    },
    copyCustomerMethod: function () {
      let method = 'post'
      if (this.customerMethod) {
        method = this.customerMethod
      }
      return method
    }
  },
  watch: {
    templateProvince: {
      handler(val, oldVal) {
        if (val !== oldVal) {
          this.cityData.splice(0, 1, val)
          this.debounceInit();
        }
      },
    },
    templateCity: {
      handler(val, oldVal) {
        if (val !== oldVal) {
          this.cityData.splice(1, 1, val)
          this.debounceInit();
        }
      },
    },
    templateCounty: {
      handler(val, oldVal) {
        if (val !== oldVal) {
          this.cityData.splice(2, 1, val)
          this.debounceInit();
        }
      },
    },
    copyCustomerUrl(val, oldVal){
      if (val && val !== oldVal){
        this.debounceInit();
      }
    }
  }
};
</script>

