<template>
  <div>
    <n-checkbox
      v-if="config?.selectAll"
      v-model:checked="state.checkAll"
      :indeterminate="state.indeterminate"
      :disabled="disable"
      :on-update:checked="onCheckAllChange"
    >
      全选
    </n-checkbox>
    <div class="col-12 fl-px-xs" style="max-height: 200px; overflow: auto">
      <div
        v-for="(item, idx) in filteredOptions"
        :key="idx"
        class="fl-mt-sm fl-pa-sm"
        style="border-radius: 3px; border: #e0e0e6 1px solid"
      >
        <div>
          <n-checkbox
            :disabled="disable"
            v-model:checked="item.checkAll"
            :indeterminate="item.indeterminate"
            :on-update:checked="(e) => handleCheckSelect(e, item)"
            ><span
              class="fl-mn-xs"
              style="font-size: 14px; color: #333639; font-weight: 600"
              >{{ item.label }}</span
            >
          </n-checkbox>
        </div>

        <div
          style="height: 1px; width: 100%; background: #e0e0e6"
          class="fl-mb-sm"
        ></div>

        <n-checkbox
          v-for="(peo, peoIdx) in item.people"
          :key="item.label + ' ' + peoIdx"
          :disabled="disable"
          v-model:checked="peo.checked"
          :on-update:checked="(e) => handleChildCheckSelect(e, peo, item)"
          ><span style="font-size: 12px; color: #333639">{{
            peo.label
          }}</span></n-checkbox
        >
      </div>
    </div>
  </div>
</template>
<script setup>
import { CloseCircleOutlined } from "@ant-design/icons-vue";
import {
  reactive,
  onBeforeMount,
  onMounted,
  getCurrentInstance,
  watch,
  nextTick,
  ref,
} from "vue";
const currentInstance = getCurrentInstance();
const { $request } = currentInstance.appContext.config.globalProperties;
import { processError } from "@/utils/helper/message";
import { getParamsByObj } from "@/utils/helper/form";
import { ItemGroup } from "ant-design-vue/lib/menu";

const emit = defineEmits(["triggerUpdateVal"]);
let props = defineProps({
  config: Object,
  fatherData: Object,
  disable: Boolean,
  val: [Array, String, Number],
});
const state = reactive({
  options: [],
  selectOptions: [],

  checkAll: false,
  indeterminate: false,
});
onBeforeMount(() => {
  getOptions();
});

const filteredOptions = ref([]);

watch(
  () => state.options,
  (newOptions) => {
    filteredOptions.value = newOptions.filter(
      (item) => item.label !== "开发测试用部门"
    );
  },
  { deep: true }
);

filteredOptions.value = state.options.filter(
  (item) => item.label !== "开发测试用部门"
);
watch(
  () => filteredOptions,
  (val) => {
    let notSelectAll = false;
    filteredOptions.value.forEach((item) => {
      item.people.forEach((peo) => {
        //存在未选中情况
        if (!peo.checked) {
          notSelectAll = true;
        }
      });
    });
    state.indeterminate = !!state.selectOptions.length && notSelectAll;

    state.checkAll = !notSelectAll;
  },
  { deep: true }
);

const getOptions = () => {
  if (props.config.optionsConfig) {
    let url = props.config.optionsConfig.url;
    let params = getParamsByObj(
      {},
      props.config.optionsConfig.params,
      props.fatherData
    );
    $request.HTTP.components.postDataByParams(url, params).then(
      (res) => {
        if (res.status === 0) {
          let data = [];
          if (props.config.optionsConfig.resDataField) {
            data = res.data[props.config.optionsConfig.resDataField];
          } else {
            data = res.data.Data || [];
          }
          let noComp = [];
          let newData = [];
          data.forEach(({ NickName, ID, Departments }) => {
            let obj = {
              label: NickName,
              value: ID,
              comp: Departments ? Departments.map(JSON.stringify) : [],
            };
            if (!Departments)
              noComp.push({ label: NickName, value: ID, checked: false });
            newData.push(obj);
          });
          // 获取列表部门集合
          let depArr = new Set();
          newData.forEach((it) => {
            it.comp.forEach((ic) => {
              depArr.add(ic);
            });
          });
          depArr = [...depArr];
          // 部门集合转对象格式
          let depArrObj = depArr.map((item) => {
            return {
              labelJson: item,
              label: JSON.parse(item).Name,
              checkAll: false,
              people: [],
            };
          });
          // 部门集合对象写入部门成员
          newData.forEach((item) => {
            depArrObj.forEach((dep) => {
              if (item.comp.includes(dep.labelJson)) {
                item.checked = false;
                dep.people.push(item);
              }
            });
          });
          // 计算最终整合数据
          state.options = depArrObj;
          state.options.push({
            label: "无归属部门",
            people: noComp,
          });
        } else {
          processError(res.message || "操作失败");
        }
      },
      (err) => {
        processError(err.message);
      }
    );
  }
};
const onCheckAllChange = (checked) => {
  state.selectOptions = [];
  filteredOptions.value.forEach((item) => {
    item["checkAll"] = checked;
    item.people.forEach((peo) => {
      peo["checked"] = checked;
      if (checked) {
        state.selectOptions.push(peo);
      }
    });
    let peoCheckLength = item.people.filter(
      (peo) => peo.checked === true
    ).length;
    item.indeterminate =
      peoCheckLength > 0 && peoCheckLength !== item.people.length;
  });
  state.indeterminate = false;
  calcCheckDefaultDepartment();
};
// 第一层
const handleCheckSelect = (checked, item) => {
  let selectOptArrJSon = JSON.parse(JSON.stringify(state.selectOptions));
  selectOptArrJSon = selectOptArrJSon.map((obj) => {
    return JSON.stringify(obj);
  });
  item["checkAll"] = checked;
  item.indeterminate = false;
  if (checked) {
    // 遍历部门 列出部门人员 放入selectOptions
    item.people.forEach((peo) => {
      peo["checked"] = checked;
      if (!selectOptArrJSon.includes(JSON.stringify(peo))) {
        state.selectOptions.push(peo);
      }
    });
  } else {
    // 遍历部门 从selectOptions去除 部门人员
    item.people.forEach((peo) => {
      peo["checked"] = checked;
      state.selectOptions.forEach((item, idx) => {
        if (JSON.stringify(item) === JSON.stringify(peo)) {
          state.selectOptions.splice(idx, 1);
        }
      });
    });
  }
  calcCheckDefaultDepartment();
};
// 第二层
const handleChildCheckSelect = (checked, peo, item) => {
  peo.checked = checked;
  let peoCheckLength = item.people.filter((peo) => peo.checked === true).length;
  item.checkAll = false;
  item.indeterminate =
    peoCheckLength > 0 && peoCheckLength !== item.people.length;
  if (peoCheckLength > 0 && peoCheckLength === item.people.length) {
    item.checkAll = true;
  }
  if (checked) {
    state.selectOptions.push(peo);
  } else {
    state.selectOptions.forEach((item, idx) => {
      if (item.value === peo.value) {
        state.selectOptions.splice(idx, 1);
      }
    });
  }
  calcCheckDefaultDepartment();
};
const calcCheckDefaultDepartment = () => {
  // 这里单独处理 在提交时选中开发测试用部门下的所有人员
  let defaultCheckDep = state.options.filter(
    (item) => item.label === "开发测试用部门"
  );
  if (defaultCheckDep.length === 1) {
    defaultCheckDep = JSON.parse(JSON.stringify(defaultCheckDep[0].people));
    state.selectOptions.map((item) => {
      if (
        defaultCheckDep.filter((peo) => peo.value === item.value).length === 0
      ) {
        defaultCheckDep.push(item);
      }
    });
  }
  emit("triggerUpdateVal", {
    defaultCheckDep: defaultCheckDep,
    selectOptions: state.selectOptions,
  });
};
</script>
