/*
 * @Author: wfl
 * @LastEditors: wfl
 * @description:
 * @updateInfo:
 * @Date: 2022-08-11 14:03:56
 * @LastEditTime: 2022-08-12 11:14:19
 */
import { isRef, watch } from 'vue';

export const useRoleHook = (roleData) => {
  if (!isRef(roleData)) {
    throw new TypeError('useRoleHook: roleData must be an Ref');
  }

  const deepSetList = (data) => {
    let list = [...data];
    data.forEach((item) => {
      if (item.children || item.__children) {
        list = [...list, ...deepSetList(item.children || item.__children)];
      }
    });
    return list;
  };

  // hooks监听Ref数据变化
  watch(roleData, (newVal) => {
    roleData = newVal;
  });

  // 遍历赋值
  const deepMap = (data, checked) => {
    data.forEach((item) => {
      item.checked = checked;
      item.indeterminate = false;
      if (item.children || item.__children) {
        deepMap(item.children || item.__children, checked);
      }
    });
  };

  // 向上依次寻找父级
  const findParent = (data, child) => {
    for (const item of data) {
      if (item.id === child.parentId) {
        return item;
      } else if (item.children) {
        const self = findParent(item.children, child);
        if (self) return self;
      }
    }
  };

  const deepMapParent = async (data, checked) => {
    const parent = await findParent(roleData, data);
    if (parent) {
      const children = parent?.children || parent?.__children;
      const allChecked = children.every((item) => item.checked);
      if (allChecked) {
        parent.checked = true;
        parent.indeterminate = false;
        deepMapParent(parent, checked);
      } else {
        parent.checked = false;
        const someChecked = children.some((item) => item.checked);
        if (someChecked) {
          parent.indeterminate = true;
        } else {
          const someIndete = children.some((item) => item.indeterminate);
          parent.indeterminate = someIndete;
        }
        deepMapParent(parent, checked);
      }
    }
  };

  const handChangeCheck = (item) => {
    const { checked, children, __children } = item;
    if (checked) {
      item.checked = true;
      item.indeterminate = false;
    }
    if (children?.length || __children?.length) {
      deepMap(children || __children, checked);
    }
    deepMapParent(item, checked);
  };

  return {
    handChangeCheck,
    deepMapParent,
    deepSetList,
  };
};
