import { defineStore } from 'pinia';
import { ref, computed } from 'vue';

// import { getEnfMineTree } from '/@/api/sys/menu';
// import { getUserMinePermissionData } from '/@/components/Form/src/jeecg/components/MineCascader/mineData.api';
import { findNode, findNodeAll, findPath, forEach } from '/@/utils/helper/treeHelper';
import { isArray, isFunction, isNil, get } from 'lodash-es';
import { getEnfMineTree } from '/@/api/sys/menu';
import { EnfMineTreeItem } from '/@/api/sys/model/menuModel';

export interface MineDepartment extends EnfMineTreeItem {
  /** 唯一标识 */
  id: string;
  /** 原本的标识 */
  rawid: string;
  /** 部门名称 */
  departName: string;
  /** 父部门ID */
  parentId: string;
  /** 是否为叶子节点（矿井是叶子节点） */
  isLeaf: boolean;
  /** 子部门列表 */
  childDepart: MineDepartment[];
  /** 传真，用作矿井编号（矿井编码） */
  fax: string;
  /** 是否禁用，没有子节点的部门即禁用 */
  disabled?: boolean;
}

const DEFAULT_CONFIG = {
  id: 'id',
  pid: 'parentId',
  children: 'childDepart',
};

export const useMineDepartmentStore = defineStore('mine-department-store', () => {
  // ==================== State 定义 ====================
  /** 当前用户的根部门 */
  const root = ref<MineDepartment>();

  /** 当前选中的部门，可能是执法处、区或者具体到矿井 */
  const depart = ref<MineDepartment>();

  /** 组织树（经过过滤等处理后的树） */
  const departTree = ref<MineDepartment[]>([]);

  /** 原始组织树（保存原始数据，用于恢复或重新过滤） */
  // const rawTree = ref<MineDepartment[]>([]);

  // ==================== Getter 计算属性 ====================
  /** 获取当前用户的根部门 */
  const getRoot = computed(() => root.value);

  /** 获取当前用户的根部门ID */
  const getRootId = computed(() => root.value?.id);

  /** 获取当前选中的部门 */
  const getDepart = computed(() => depart.value);

  /** 获取当前选中的部门ID */
  const getDepartId = computed(() => depart.value?.id);

  /** 获取组织树 */
  const getDepartTree = computed(() => departTree.value);

  /** 获取当前选中的部门在组织树中的访问路径 */
  const getDepartPath = computed(() => {
    return calcDepartPathById(getDepartId.value, getDepartTree.value);
  });

  // ==================== Action 方法 ====================

  /**
   * 设置当前选中的部门
   * @param dep - 部门对象
   */
  function setDepart(dep?: MineDepartment) {
    // if (isNil(dep) || isEmpty(dep)) return;
    depart.value = dep;
  }

  /**
   * 根据部门ID设置当前选中的部门
   * @param id - 部门ID，默认为空字符串
   */
  function setDepartById(id: string = '') {
    const node = findDepartById(id, departTree.value);
    setDepart(node);
  }

  /**
   * 获取组织树数据（异步）
   * 2. getEnfMineTree: 获取矿井（叶子节点）数据
   */
  async function fetchDepartTree() {
    try {
      // 并行请求两个接口
      const res = (await getEnfMineTree()) as MineDepartment;
      if (!res) return;
      const LEAF_LEVEL_ORG = get(res, 'memoDesc[2]', '4');

      forEach(
        [res],
        (node: MineDepartment) => {
          node.isLeaf = node.orgType === LEAF_LEVEL_ORG;
          node.disabled = node.isLeaf ? false : !Boolean(node.childDepart.length);
          node.rawid = node.id;
        },
        DEFAULT_CONFIG
      );

      root.value = res;
      depart.value = res;
      departTree.value = [res];
      // departTree.value = res.isLeaf ? [res] : res.childDepart;
      // 深拷贝保存原始数据，用于过滤后恢复
      // rawTree.value = JSON.parse(JSON.stringify(tree));

      // 如果需要自动选中第一个叶子节点（矿井），可以取消注释以下代码
      /*
      if (!depart.value) {
        const firstLeaf = findNode(
          tree, 
          (item) => item.isLeaf, 
          DEFAULT_CONFIG
        );
        if (firstLeaf) {
          setDepart(firstLeaf);
        }
      }
      */
    } catch (error) {
      console.error('获取组织树数据失败:', error);
      throw error;
    }
  }

  /**
   * 清除选中的部门
   */
  function clearDepart() {
    depart.value = undefined;
  }

  /**
   * 工具函数，过滤组织树并返回，不改变组织树数据
   * @param fn - 过滤函数，返回true表示保留该节点
   */
  function filterDepartTree(fn: (node: MineDepartment) => boolean) {
    // 只有在有原始数据时才进行过滤
    if (departTree.value.length > 0) {
      return findNodeAll(departTree.value, fn, DEFAULT_CONFIG);
    }
    return [];
  }

  /**
   * 工具函数，获取走到所选部门必要路径
   */
  function calcDepartPathById<T>(id?: string, depart?: MineDepartment, mapFn?: (node: MineDepartment) => T): T[];
  function calcDepartPathById<T>(id?: string, depart?: (MineDepartment | undefined)[], mapFn?: (node: MineDepartment) => T): T[];
  function calcDepartPathById<T>(id?: string, depart?: MineDepartment | (MineDepartment | undefined)[], mapFn?: (node: MineDepartment) => T) {
    if (!id) return [];
    if (!depart) return [];
    if (!isArray(depart)) {
      depart = [depart];
    }
    const path = findPath(depart, (e) => e.id === id, DEFAULT_CONFIG);

    if (!isArray(path)) {
      return [];
    }
    if (isFunction(mapFn)) {
      return path.map(mapFn);
    }
    return path;
  }

  function findDepartById(id?: string, depart?: MineDepartment): MineDepartment | undefined;
  function findDepartById(id?: string, depart?: (MineDepartment | undefined)[]): MineDepartment | undefined;
  function findDepartById(id?: string, depart?: MineDepartment | (MineDepartment | undefined)[]): MineDepartment | undefined {
    if (!id) return;
    if (!depart) depart = departTree.value;
    if (!isArray(depart)) {
      depart = [depart];
    }

    return findDepart((e) => e.id === id, depart);
  }

  function findDepart(fn: (node: MineDepartment) => boolean, depart?: MineDepartment): MineDepartment | undefined;
  function findDepart(fn: (node: MineDepartment) => boolean, depart?: (MineDepartment | undefined)[]): MineDepartment | undefined;
  function findDepart(fn: (node: MineDepartment) => boolean, depart?: MineDepartment | (MineDepartment | undefined)[]): MineDepartment | undefined {
    if (!fn || typeof fn !== 'function') return;
    if (!depart) return;
    if (!isArray(depart)) {
      depart = [depart];
    }

    const node = findNode(depart, fn, DEFAULT_CONFIG);
    if (isNil(node)) return;
    return node;
  }

  // ==================== 暴露的属性和方法 ====================

  return {
    // --- State（可修改）---
    depart,
    departTree,

    // --- Getter（只读计算属性）---
    getRoot,
    getRootId,
    getDepart,
    getDepartId,
    getDepartTree,
    getDepartPath,

    // --- Action（操作方法）---
    setDepart,
    setDepartById,
    // setDepartTree,
    fetchDepartTree,
    filterDepartTree,
    clearDepart,
    calcDepartPathById,
    findDepartById,
    findDepart,
  };
});
