<!-- @format -->

<template>
  <div>
    <a-input
      placeholder="请选择"
      readonly="readonly"
      style="cursor: pointer"
      v-model:value="choiceCityName"
      @click.stop="showCard">
      <template #suffix> <ns-icon name="drow" size="12" @click.stop="showCard" /></template>
    </a-input>
    <div v-show="visible" class="selectCard">
      <header class="card_header">
        <div :style="{ background: regionLevel === 1 ? '#fff' : '' }" @click.stop="check(1)"
          >省</div
        >
        <div :style="{ background: regionLevel === 2 ? '#fff' : '' }" @click.stop="check(2)"
          >市</div
        >
        <div :style="{ background: regionLevel === 3 ? '#fff' : '' }" @click.stop="check(3)"
          >区</div
        >
      </header>
      <ul>
        <li
          :class="choiceCity[regionLevel - 1] === item.name ? 'isChoice' : ''"
          @click.stop="choiceItem(item)"
          v-for="item in data[regionLevel]"
          :key="item.code"
          >{{ item.name }}</li
        >
      </ul>
    </div>
  </div>
</template>

<script lang="ts">
  import { cloneDeep, isArray, isEqual, isObject } from 'lodash-es';
  import { defineComponent, ref, watch, computed, onMounted } from 'vue';
  import { http } from '/nerv-lib/util/http';
  export default defineComponent({
    name: 'NsInputCityV2',
    props: {
      value: {
        type: Array,
        default: () => {
          return [];
        },
      },
      defaultValue: {
        type: Array,
        default: () => {
          return [];
        },
      },
      api: {
        type: String,
        default: '',
      },
      fieldMap: {
        type: Object || Array,
        default: () => {
          return [];
        },
      },
      formModel: {
        type: Object || Array,
      },
      isSeparate: {
        type: Boolean,
        default: false,
      },
    },
    emits: ['change'],
    setup(props, { emit }) {
      // console.log(props);
      const visible = ref(false);
      const hasload = ref(false);
      let choiceCity = ref<any[]>([]);
      let choiceCityName = ref('');
      let province = ref([]); //省
      let city = ref([]); //市
      let area = ref([]); //区
      const data = ref([]);
      data.value[1] = province.value;
      const regionLevel = ref(1);

      const showCard = () => {
        visible.value = true;
      };
      const closeCard = () => {
        visible.value = false;
      };
      const check = (e) => {
        regionLevel.value = e;
        initData(regionLevel.value);
      };

      const choiceItem = (e: any) => {
        let currObject = [
          { name: 0, code: 3, enmpitIndex: [1, 2, 4, 5] },
          { name: 1, code: 4, enmpitIndex: [2, 5] },
          { name: 2, code: 5, enmpitIndex: [] },
        ];
        let enmpitIndex = [[1, 2, 4, 5], [2, 5], []][regionLevel.value - 1];
        let cureleve: { name: number; code: number; enmpitIndex: any[] } =
          currObject[regionLevel.value - 1];
        const update = () => {
          let copecity = cloneDeep(choiceCity.value);
          Object.keys(cureleve).forEach((el: string) => {
            let index = cureleve[el];
            let value = e[el];
            copecity[index] = value;
          });
          enmpitIndex.forEach((el) => {
            copecity[el] = null;
          });
          choiceCity.value = [...copecity];
        };
        switch (regionLevel.value) {
          case 1:
            update();
            regionLevel.value = 2;
            initData(2, e.code);
            break;
          case 2:
            update();
            regionLevel.value = 3;
            initData(3, e.code);
            break;
          case 3:
            update();
            closeCard();
            break;
        }
      };
      const initData = (regionLevel: Number, code?: Number) => {
        let parentcode = '';
        switch (regionLevel) {
          case 1:
            province.value = [];
            data.value[2] = [];
            data.value[3] = [];
            break;
          case 2:
            parentcode = choiceCity.value[3];
            city.value = [];
            data.value[3] = [];
            break;
          case 3:
            parentcode = choiceCity.value[4];
            area.value = [];
            break;
        }
        async function getDate() {
          try {
            let body: Recordable = {};
            body['regionLevel'] = regionLevel;
            if (parentcode || regionLevel == 1) {
              body.parentCode = parentcode;
              const res = await http.get(props.api || '/api/pension/pension/objs/BaseArea', body);
              if (res.success) {
                switch (regionLevel) {
                  case 1:
                    province.value = res.data;
                    break;
                  case 2:
                    city.value = res.data;
                    break;
                  case 3:
                    area.value = res.data;
                    break;
                }
                data.value[regionLevel] = res.data;
              }
            }
          } catch (err) {
            console.log(err);
          }
        }
        getDate();
      };
      const updateValue = (newv) => {
        let leve = 0;
        let code = '';
        let cityMap = newv;
        newv.forEach((el, i) => {
          if (el) {
            leve = i;
          }
        });
        if (!props.isSeparate) {
          regionLevel.value = leve > 0 ? leve : 1;
        } else {
          regionLevel.value = leve > 2 ? leve - 2 : 1;
        }
        regionLevel.value == 1 ? '' : (code = cityMap[leve - 1]);
        if (!props.isSeparate) {
          newv.forEach((el, i) => {
            if (i === 0) {
              let cityNameList = el.split('/');
              cityNameList.forEach((item, index) => {
                cityMap[index] = item;
              });
            } else {
              cityMap[i + 3] = el;
            }
          });
        } else {
          cityMap = newv;
        }
        choiceCity.value = cityMap;
        initData(regionLevel.value, code);
      };

      onMounted(() => {
        initData(regionLevel.value);
        if (isArray(props.value) && props.value.length) {
          updateValue(props.value);
        }
        if (props.defaultValue.length) {
          updateValue(props.defaultValue);
        }
      });

      watch(
        () => choiceCity.value,
        (newv, oldv) => {
          if (newv) {
            let list = [];
            newv.forEach((el, i) => {
              if (el && i < 3) {
                list.push(el);
              }
            });
            choiceCityName.value = list.join('/');
            if (!props.isSeparate) {
              emit('change', [choiceCityName, ...newv.slice(1)]);
            } else {
              emit('change', newv);
            }
          }
        },
      );

      watch(
        () => props.value,
        (newv, oldv) => {
          if (!isEqual(newv, oldv) && !isEqual(newv, choiceCity.value)) {
            updateValue(newv);
          }
          if (props.value?.length > 5 && props.value[4]) {
            regionLevel.value = 3;
            initData(regionLevel.value);
          }
        },
      );

      watch(
        () => props.formModel,
        (newv, oldv) => {
          if (newv && !props.value.length && props.fieldMap.length && !hasload.value) {
            let cityMap = [];
            let leve = 0;
            let code = '';
            props.fieldMap.forEach((el, i) => {
              cityMap[i] = newv[el];
              if (newv[el]) {
                leve = i;
              }
            });
            if (!props.isSeparate) {
              regionLevel.value = leve > 0 ? leve : 1;
            } else {
              regionLevel.value = leve > 2 ? leve - 2 : 1;
            }
            regionLevel.value == 1 ? '' : (code = cityMap[leve - 1]);
            // choiceCity.value = cityMap;
            updateValue(cityMap, code);
            hasload.value = true;
          }
        },
      );
      watch(
        () => visible.value,
        (val) => {
          val
            ? document.body.addEventListener('click', closeCard)
            : document.body.removeEventListener('click', closeCard);
        },
      );

      return {
        choiceCity,
        showCard,
        closeCard,
        regionLevel,
        check,
        choiceItem,
        visible,
        province,
        city,
        area,
        data,
        choiceCityName,
      };
    },
  });
</script>
<style lang="less" scoped>
  .selectCard {
    position: absolute;
    z-index: 4;
    width: 300px;
    height: 180px;
    transform: translateY(5px);
    box-shadow: 0 2px 8px rgb(0 0 0 / 15%);
    animation: move-down 0.5s;
    background: #fff;
    border: 1px solid #ccc;
    .card_header {
      width: 100%;
      height: 26px;
      background: rgb(238, 238, 238);
      display: flex;
      justify-content: space-between;
      border-bottom: 1px solid #ccc;
      div {
        text-align: center;
        width: 34%;
        cursor: pointer;
      }
    }
    ul {
      width: 100%;
      height: 150px;
      overflow: auto;
      list-style: none;
      padding: 10px;
      li {
        line-height: 30px;
        cursor: pointer;
        padding-left: 10px;
        &:hover {
          background-color: rgba(3, 141, 218, 0.1);
        }
      }
    }
  }
  .isChoice {
    color: rgb(3, 141, 218);
  }
  @keyframes move-down {
    0% {
      transform: scale(0);
      height: 0px;
      opacity: 0;
    }
    100% {
      transform: scale(1);
      height: 180px;
      opacity: 1;
    }
  }
</style>