<!-- eslint-disable vue/v-on-event-hyphenation -->
<template>
  <div>
    <div class="search-input">
      <a-input
        v-model:value="searchValue"
        :placeholder="placeholder"
        @pressEnter="onSearch"
        :bordered="false" />
      <ns-icon class="iconfont" style="margin: auto" name="search" />
    </div>
    <div class="checkbox-content">
      <p class="selectLevel">
        <span
          v-for="(item, index) in selectLevel"
          :key="index"
          @click="checkSelectLevel(item, index)">
          <span v-if="index != 0">></span>
          <span
            :class="index == selectLevel.length - 1 ? 'selectLevel-last-span' : 'selectLevel-span'"
            >{{ item.name }}</span
          >
        </span>
      </p>
      <div class="candidate-content" v-if="candidateValues.length > 0">
        <div style="padding: 4px 0px" v-if="filterMultiple">
          <a-checkbox
            :indeterminate="state.indeterminate"
            v-model:checked="state.checkAll"
            @change="onCheckAllChange">
            全选
          </a-checkbox>
        </div>
        <div v-for="(item, index) in candidateValues" :key="index" class="checkbox">
          <a-checkbox
            v-if="filterMultiple"
            v-model:checked="item.checked"
            @change="onCheckChange($event, item)"
            >{{ item.name }}</a-checkbox
          >
          <a-radio v-else v-model:checked="item.checked" @click="onCheckChangeRadio(item)">{{
            item.name
          }}</a-radio>
          <span
            v-if="searchType == 'dept'"
            @click="checkSubordinate(item)"
            :class="
              item.subordinateDisable ? 'checkbox-subordinate-disable' : 'checkbox-subordinate'
            ">
            <ns-icon
              class="iconfont"
              style="margin: auto; width: 12px; height: 12px"
              :name="item.subordinateDisable ? 'subordinate-dis' : 'subordinate'" />
            下级</span
          >
        </div>
      </div>
      <div v-if="candidateValues.length <= 0 && ifLoading">
        <a-result title="暂无相关部门/人员">
          <template #icon>
            <ns-icon
              class="iconfont"
              style="margin: auto; width: 120px; height: 120px"
              name="noSearchData" />
          </template>
        </a-result>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
  import { computed, inject, reactive } from 'vue';
  import { watch } from 'vue';
  import { defineComponent, ref, onMounted } from 'vue';
  import { http } from '../../util/http';
  import { remove } from 'lodash-es';
  import { unref } from 'vue';
  import { compareArrays } from './util';
  import { Emitter } from 'mitt';

  //单独部门/人员 只区分单选或多选
  export default defineComponent({
    name: 'NsShuttleFrameDeptOrMember',
    props: {
      //是否多选
      filterMultiple: {
        type: Boolean,
        default: false,
      },
      placeholder: String,
      searchType: {
        type: String,
        default: 'account',
      },
      // componentRef: String,
      api: {
        type: Object,
        // eslint-disable-next-line vue/require-valid-default-prop
        default: {
          account: '/api/passport/passport/objs/DepartmentAccounts',
          dept: '/api/passport/passport/objs/Department',
        },
      },
    },
    emits: ['selected'],
    setup(props, ctx) {
      const lmEmitter = inject('lmEmitter') as Emitter<emitEvents>;
      // function initData() {
      //   if (props.searchType == 'dept') {
      //     organizationGet();
      //   } else {
      //     accountGet();
      //   }
      // }
      // initData();

      lmEmitter.on('deleteAllSelected', (data) => {
        deleteAllSelected();
      });

      lmEmitter.on('deleteSelected', (data) => {
        deleteSelected(data);
      });

      //全部的值
      const departmentAllData = ref([]);
      const accountAllData = ref([]);
      const ifLoading = ref(false);
      //展示的候选值
      const candidateValues = ref([]);
      //选中的层级
      const selectLevel = ref<any>([]);
      //选中的值
      const selectedValue = ref<any>([]);

      //获取部门的值
      async function organizationGet() {
        let data = await http.get(
          props.api.dept,
          { pageSize: 9999, levelID: 0 },
          { timeout: 120 * 1000 },
        );
        return data;
      }

      //获取人员的值
      async function accountGet() {
        await http.get(props.api.account, { pageSize: 9999 }, { timeout: 120 * 1000 });
      }

      const state = reactive({
        indeterminate: false,
        checkAll: false,
        checkedList: [],
      });

      const onCheckAllChange = (e: any) => {
        Object.assign(state, {
          indeterminate: false,
          checkAll: e.target.checked,
        });
        //全选
        if (e.target.checked) {
          //selectedValue.value 需要不影响之前的选中
          state.checkedList = [];
          candidateValues.value.map((item) => {
            state.checkedList.push(item.ID);
            const ret = selectedValue.value.find((ev: { id: any }) => {
              return ev.id === item.ID;
            });
            if (ret == undefined) {
              selectedValue.value.push({
                type: props.searchType,
                id: item.ID,
                name: item.name,
              });
            }
            item.subordinateDisable = true;
            item.checked = e.target.checked;
          });
        } else {
          state.checkedList = [];
          candidateValues.value.map((item) => {
            remove(unref(selectedValue.value), (elem: object) => {
              return elem.id === item.ID;
            });
            item.subordinateDisable = false;
            item.checked = e.target.checked;
          });
        }
      };

      watch(
        () => state.checkedList,
        (val) => {
          state.indeterminate = !!val.length && val.length < candidateValues.value.length;
          state.checkAll =
            val.length === candidateValues.value.length && candidateValues.value.length > 0;
        },
        { deep: true },
      );

      // watch(
      //   () => selectedValue.value,
      //   (val) => {
      //     val.map((elem) => {
      //       elem.componentRef = props.componentRef;
      //     });
      //   },
      //   { immediate: true, deep: true },
      // );

      const selectedValueCopy = computed(() => JSON.parse(JSON.stringify(selectedValue.value)));
      watch(
        () => selectedValueCopy.value,
        (newData, old) => {
          let val = [];
          let delVal = [];
          if (props.filterMultiple) {
            //新增
            if (!old || newData.length > old.length) {
              val = compareArrays(newData, old);
              ctx.emit('selected', val, 'add');
            }
            //删除
            else {
              delVal = compareArrays(old, newData);
              ctx.emit('selected', delVal, 'del');
            }
          } else {
            //取消选择
            if (newData.length == 0 && old) {
              ctx.emit('selected', old, 'del');
            }
            //切换选择
            else if (old) {
              ctx.emit('selected', newData, 'add');
              ctx.emit('selected', old, 'del');
            }
          }
        },
        { immediate: true, deep: true },
      );

      const onCheckChange = (e: any, item: object) => {
        if (e.target.checked) {
          state.checkedList.push(item.ID);
          selectedValue.value.push({
            type: props.searchType,
            id: item.ID,
            name: item.name,
          });
          candidateValues.value.map((elem) => {
            if (item.ID === elem.ID) {
              elem.subordinateDisable = true;
            }
          });
        } else {
          remove(unref(state.checkedList), (elem: object) => {
            return elem === item.ID;
          });
          remove(unref(selectedValue.value), (elem: object) => {
            return elem.id === item.ID;
          });
          candidateValues.value.map((elem) => {
            if (item.ID === elem.ID) {
              elem.checked = false;
              elem.subordinateDisable = false;
            }
          });
        }
      };

      function checkSubordinate(item: { subordinateDisable: any; ID: any; name: any }) {
        if (item.subordinateDisable) return;
        state.checkedList = [];
        selectLevel.value.push({
          id: item.ID,
          name: item.name,
        });
        candidateValues.value = departmentAllData.value.filter(function (elem) {
          return elem.levelID == item.ID;
        });
      }

      function checkSelectLevel(item: { id: any }, index: number) {
        if (index == selectLevel.value.length - 1) return;
        selectLevel.value.forEach((elem: { id: any }, index: number) => {
          if (elem.id == item.id) {
            selectLevel.value.splice(index + 1, selectLevel.value.length - 1);
          }
        });
        candidateValues.value = departmentAllData.value.filter(function (elem) {
          return elem.levelID == item.id;
        });
        if (!props.filterMultiple) {
          let ifSelected = candidateValues.value.filter(function (elem) {
            return elem.checked == true;
          });
          //说明选中了,之前的选中要删除
          if (ifSelected.length > 0 && ifSelected[0].ID !== selectedValue.value[0].id) {
            candidateValues.value.map((elem) => {
              elem.checked = false;
              elem.subordinateDisable = false;
            });
          }
        }
      }

      function getSelectedValue() {
        // selectedValue.value.map((elem) => {
        //   elem.componentRef = props.componentRef;
        // });
        return selectedValue.value;
      }

      //单选场景
      const onCheckChangeRadio = (item: object) => {
        console.log(item.checked);
        if (!item.checked) {
          selectedValue.value = [
            {
              type: props.searchType,
              id: item.ID,
              name: item.name,
            },
          ];
          candidateValues.value.map((elem) => {
            elem.checked = item.ID === elem.ID;
            elem.subordinateDisable = item.ID === elem.ID;
          });
        } else {
          remove(unref(selectedValue.value), (elem: object) => {
            return elem.id === item.ID;
          });
          candidateValues.value.map((elem) => {
            if (item.ID === elem.ID) {
              elem.checked = false;
              elem.subordinateDisable = false;
            }
          });
        }
        console.log('selectedValue', selectedValue.value);
      };

      //删除已选择
      function deleteSelected(item: { type: string; id: object }) {
        console.log('deleteSelected', item);
        if (item.type == 'dept') {
          candidateValues.value.map((elem) => {
            if (elem.ID == item.id) {
              elem.subordinateDisable = false;
              elem.checked = false;
            }
          });
          remove(unref(state.checkedList), (elem: object) => {
            return elem.deptID === item.id && elem.type == item.type;
          });
        } else {
          candidateValues.value.map((elem) => {
            if (elem.ID == item.id) {
              elem.checked = false;
            }
          });
          remove(unref(state.checkedList), (elem: object) => {
            return elem === item.id;
          });
        }
        remove(unref(selectedValue.value), (elem: object) => {
          return elem.id === item.id && elem.type == item.type;
        });
      }

      //清空已选择
      function deleteAllSelected() {
        state.checkedList = [];
        selectedValue.value = [];
        candidateValues.value.map((elem) => {
          elem.checked = false;
        });
      }

      const searchValue = ref();

      function onSearch() {
        if (selectLevel.value.length > 1) {
          selectLevel.value = selectLevel.value.splice(0, selectLevel.value.length - 1);
        }
        if (props.searchType == 'account') {
          candidateValues.value = accountAllData.value.filter(function (item) {
            return item.name.includes(searchValue.value);
          });
        } else {
          candidateValues.value = departmentAllData.value.filter(function (item) {
            return item.name.includes(searchValue.value);
          });
        }
      }

      function formatOrganizationData(data: { data: string | any[] }) {
        if (data.data.length > 0) {
          selectLevel.value.push({
            id: 0,
            name: data.data[0].tenant,
          });
          let selectedList: any[] = [];
          selectedValue.value.map((item: { id: any }) => {
            selectedList.push(item.id);
          });
          departmentAllData.value = data.data;
          initSelectedOrgan();
        }
      }

      function initSelectedOrgan() {
        let selectedList: any[] = [];
        selectedValue.value.map((item: { id: any }) => {
          selectedList.push(item.id);
        });
        departmentAllData.value.map((item) => {
          item.subordinateDisable = selectedList.includes(item.ID);
          item.checked = selectedList.includes(item.ID);
        });
        candidateValues.value = departmentAllData.value.filter(function (item: {
          checked: boolean;
          ID: any;
          levelID: number;
        }) {
          return item.levelID == 0;
        });
      }

      function formatAccountData(data: { data: { tenant: any }[] }) {
        if (data.data.length > 0) {
          selectLevel.value.push({
            id: 0,
            name: data.data[0].tenant,
          });
          let selectedList: any[] = [];
          selectedValue.value.map((item: { id: any }) => {
            selectedList.push(item.id);
          });
          data.data.map((item: { subordinateDisable: boolean; ID: any; checked: boolean }) => {
            item.subordinateDisable = selectedList.includes(item.ID);
            item.checked = selectedList.includes(item.ID);
          });
          accountAllData.value = data.data;
          candidateValues.value = data.data.filter(function (item: {
            checked: boolean;
            levelID: number;
          }) {
            return item.levelID == 0;
          });
          candidateValues.value = data.data;
        }
      }

      //初始化值
      lmEmitter.on('setDefaultDataMOD', (data: any) => {
        if (props.searchType == 'account') {
          accountGet().then((res) => {
            formatAccountData(res);
            if (data.length <= 0) {
              return;
            }
            setTimeout(() => {
              //单选
              initSelectedValue(accountAllData.value, data, 'account');
            }, 100);
          });
        } else {
          organizationGet().then((res) => {
            formatOrganizationData(res);
            if (data.length <= 0) {
              return;
            }
            setTimeout(() => {
              initSelectedValue(departmentAllData.value, data, 'dept');
            }, 100);
          });
        }
      });

      function initSelectedValue(list: any[], data: any[], type: string) {
        //单选
        if (!props.filterMultiple) {
          let item = list.filter(function (elem: { name: any }) {
            return elem.name == data[0].name;
          });
          data[0].id = item[0].ID;
        }
        //多选
        else {
          let nameList: any[] = [];
          data.map((item: { name: any }) => {
            nameList.push(item.name);
          });
          let dataList = list.filter(function (elem: { name: any }) {
            return nameList.includes(elem.name);
          });
          for (let index = 0; index < data.length; index++) {
            try {
              dataList.map((dl: { name: any }) => {
                if (dl.name == data[index].name) {
                  throw dl;
                }
              });
            } catch (error) {
              data[index].id = error.ID;
            }
          }
        }
        selectedValue.value = data;
        ifLoading.value = true;
        if (type == 'dept') {
          initSelectedOrgan();
        }
      }

      return {
        candidateValues,
        onCheckAllChange,
        searchValue,
        onSearch,
        onCheckChange,
        state,
        checkSubordinate,
        selectLevel,
        checkSelectLevel,
        selectedValue,
        getSelectedValue,
        onCheckChangeRadio,
        deleteSelected,
        deleteAllSelected,
        ifLoading,
      };
    },
  });
</script>
<style lang="less" scoped>
  .search-input {
    display: flex;
    border: 1px solid #dcdfe2;
    border-radius: 8px;
    padding-right: 8px;
    margin-bottom: 8px;
  }
  .checkbox {
    padding: 4px 0;

    &-subordinate {
      float: right;
      color: @primary-color;
      cursor: pointer;
    }
    &-subordinate-disable {
      float: right;
      color: #9b9b9b;
      cursor: default;
    }
  }
  .selectLevel {
    margin-bottom: 2px;

    &-last-span {
      color: #9b9b9b;
      padding: 0px 4px;
      cursor: pointer;
    }
    &-span {
      padding: 0px 4px;
      cursor: pointer;
    }
  }
  .checkbox-content {
    //overflow-y: auto;
    // min-height: 250px;
    // max-height: 350px;
    // height: 250px;
  }
  .candidate-content {
    height: 250px;
    overflow-y: auto;
  }
  :deep(.ant-result) {
    padding: 24px;
  }
  :deep(.ant-result-icon) {
    margin-bottom: 0px;
  }
  :deep(.ant-result-title) {
    color: #747677;
    text-align: center;
    font-size: 18px;
  }
</style>