import type { SysConfigInfo } from '@vben/types';

import { merge } from '@jnpf/utils';

import { defineStore } from 'pinia';

import { getDictionaryAll, getDictionaryDataSelector } from '#/api/systemData/dictionary';

interface DicChildItem {
  isTree?: number;
  id: string;
  enCode: string;
  fullName: string;
}
interface DicItem extends DicChildItem {
  dictionaryList: DicChildItem[];
}
interface BaseState {
  // 系统配置
  sysConfigInfo: Partial<SysConfigInfo>;
  dictionaryList: DicItem[];
}

/**
 * 系统配置相关
 */
export const useBaseStore = defineStore('base', {
  getters: {
    getDicList(): DicItem[] {
      return this.dictionaryList;
    },
    getSysConfig(): Partial<SysConfigInfo> {
      return this.sysConfigInfo;
    },
  },
  actions: {
    setSysConfig(config: Partial<SysConfigInfo>) {
      this.sysConfigInfo = merge(config as any, this.sysConfigInfo || {});
    },
    setDictionaryList(list: DicItem[] = []) {
      this.dictionaryList = list;
    },
    async getDictionaryAll(): Promise<DicItem[]> {
      try {
        if (this.dictionaryList.length > 0) {
          return this.dictionaryList;
        } else {
          const res = await getDictionaryAll();
          if (!res) return [];
          this.dictionaryList = res.data.list;
          return res.data.list;
        }
      } catch {
        return [];
      }
    },
    async getDictionaryData(encode: string, id: string = ''): Promise<DicChildItem | DicChildItem[]> {
      try {
        let data: Partial<DicItem> = {};
        let json: DicChildItem | DicChildItem[] = [];
        let list: DicItem[] = [];
        list = this.dictionaryList.length === 0 ? await this.getDictionaryAll() : this.dictionaryList;
        if (encode) {
          const arr = list.filter((o) => o.enCode === encode);
          if (arr.length === 0) return [];
          data = arr[0] as DicItem;
          if (id) {
            let rowData: DicChildItem[] = [];
            if (data.isTree) {
              function findData(list) {
                for (const e of list) {
                  if (e.id === id) {
                    rowData[0] = e;
                    break;
                  }
                  if (e.children && e.children.length > 0) {
                    findData(e.children);
                  }
                }
              }
              findData(data.dictionaryList);
            } else {
              rowData = (data.dictionaryList as DicChildItem[]).filter((o) => o.id === id);
            }
            json =
              rowData.length > 0
                ? (rowData[0] as DicItem)
                : {
                    id: '',
                    fullName: '',
                    enCode: '',
                  };
          } else {
            json = data.dictionaryList as DicChildItem[];
          }
          return json;
        }
        return json;
      } catch {
        return [];
      }
    },
    async getDicDataSelector(value: string, key: string = 'id'): Promise<DicChildItem[]> {
      try {
        if (!value) return [];
        const list = this.dictionaryList.length === 0 ? await this.getDictionaryAll() : this.dictionaryList;
        const cachedIndex = list.findIndex((item) => item[key] === value);
        const cached = cachedIndex === -1 ? undefined : list[cachedIndex];
        if (cached?.dictionaryList?.length) return cached.dictionaryList;

        // The persisted aggregate cache does not include dictionaries created after login.
        const res = await getDictionaryDataSelector(value);
        const options = res?.data?.list;
        if (!Array.isArray(options)) return cached?.dictionaryList || [];

        if (cached) {
          this.dictionaryList.splice(cachedIndex, 1, { ...cached, dictionaryList: options });
        } else if (key === 'id') {
          this.dictionaryList.push({ id: value, enCode: '', fullName: '', dictionaryList: options });
        }
        return options;
      } catch {
        return [];
      }
    },
    $reset() {
      this.dictionaryList = [];
    },
  },
  persist: {
    // 持久化
    pick: ['dictionaryList', 'sysConfigInfo'],
  },
  state: (): BaseState => ({
    dictionaryList: [],
    sysConfigInfo: {},
  }),
});
