/**
 * 字典数据加载 Composable (Vue 3 Composition API)
 * 
 * 使用方式：
 * 1. 在组件中导入 import { useDict } from '@/utils/composables/useDict';
 * 2. 在 setup 中调用 const { dictData, dictLoading, loadDict, getDictLabel, ... } = useDict(['sys_user_sex', 'sys_normal_disable']);
 * 3. 在模板中直接使用 dictData 对象获取字典项 v-for="item in dictData.sys_user_sex"
 */

import { ref, reactive, onMounted } from 'vue';
import { getDictData } from '@/api/services/dict';
import storage from '@/utils/storage';
import staticDict from '@/utils/staticDict';

// 全局字典缓存对象，用于存储已加载的字典数据
const dictCache = {
  // 缓存的字典数据，格式为 { dictType: [{label, value, ...}, ...] }
  data: {},
  // 缓存过期时间，单位为毫秒
  expireTime: 1000 * 60 * 60, // 1小时
  // 缓存最后更新时间
  lastUpdateTime: {},
  // 正在加载的字典类型，用于防止重复请求
  loading: {}
};

/**
 * 字典数据加载 Composable
 * @param {Array} initialDictTypes - 初始需要加载的字典类型数组
 * @param {Object} options - 配置选项
 * @param {Boolean} options.autoLoad - 是否自动加载，默认为 true
 * @returns {Object} - 返回字典相关的响应式数据和方法
 */
export function useDict(initialDictTypes = [], options = {}) {
  const { autoLoad = true } = options;
  
  // 组件中的字典数据
  const dictData = reactive({});
  
  // 字典加载状态
  const dictLoading = ref(false);
  
  // 定义组件需要加载的字典类型
  const dictTypeList = ref(initialDictTypes);

  /**
   * 从缓存中获取字典数据
   * @param {String} dictType - 字典类型
   * @returns {Array|null} - 返回字典数据，不存在或已过期则返回null
   */
  const getDictFromCache = (dictType) => {
    // 判断是否有缓存
    if (!dictCache.data[dictType]) {
      return null;
    }

    // 判断缓存是否过期
    const lastUpdateTime = dictCache.lastUpdateTime[dictType] || 0;
    const now = Date.now();
    if (now - lastUpdateTime > dictCache.expireTime) {
      // 缓存已过期，删除缓存
      delete dictCache.data[dictType];
      delete dictCache.lastUpdateTime[dictType];
      return null;
    }

    // 返回缓存的字典数据
    return dictCache.data[dictType];
  };

  /**
   * 更新字典缓存
   * @param {String} dictType - 字典类型
   * @param {Array} dictList - 字典数据列表
   */
  const updateDictCache = (dictType, dictList) => {
    dictCache.data[dictType] = dictList;
    dictCache.lastUpdateTime[dictType] = Date.now();

    // 更新本地存储
    try {
      // 只存储最后更新时间，具体数据保存在内存中
      storage.setDict(`dict_time_${dictType}`, dictCache.lastUpdateTime[dictType]);
    } catch (e) {
      console.error('更新字典缓存失败:', e);
    }
  };

  /**
   * 等待指定类型的字典加载完成
   * @param {Array} types - 字典类型数组
   * @returns {Promise} - 返回等待的Promise对象
   */
  const waitForDictLoading = (types) => {
    return new Promise(resolve => {
      const checkInterval = setInterval(() => {
        const stillLoading = types.some(type => dictCache.loading[type]);
        if (!stillLoading) {
          clearInterval(checkInterval);

          // 加载完成后，从缓存中获取数据
          types.forEach(type => {
            const cachedDict = getDictFromCache(type);
            if (cachedDict) {
              dictData[type] = cachedDict;
            }
          });

          resolve(dictData);
        }
      }, 50);
    });
  };

  /**
   * 从服务器获取字典数据
   * @param {Array} dictTypes - 字典类型数组
   * @returns {Promise} - 返回字典获取的Promise对象
   */
  const fetchDictData = (dictTypes) => {
    // 标记这些字典类型正在加载
    dictTypes.forEach(type => {
      dictCache.loading[type] = true;
    });

    // 单个字典类型
    if (dictTypes.length === 1) {
      const dictType = dictTypes[0];
      console.log(`[useDict] Fetching single dictionary: ${dictType}`);
      return getDictData(dictType).then(res => {
        if (res.data.code === 200) {
          let dictList = [];
          if (dictType === 'mall_product_category') {
            dictList.push({
              dictLabel: '推荐',
              dictValue: '-1'
            });
            dictList.push(...res.data.data);
          } else {
            dictList = res.data.data;
          }

          // 更新组件数据和缓存
          dictData[dictType] = dictList;
          updateDictCache(dictType, dictList);
          delete dictCache.loading[dictType];

          return dictList;
        } else {
          console.error(`获取字典[${dictType}]数据失败:`, res.data.msg);
          delete dictCache.loading[dictType];
          return Promise.reject(res.data.msg);
        }
      }).catch(err => {
        delete dictCache.loading[dictType];
        throw err;
      });
    }

    // 多个字典类型，并发请求
    console.log(`[useDict] Concurrently fetching ${dictTypes.length} dictionaries: ${dictTypes.join(', ')}`);

    const requests = dictTypes.map(dictType => {
      return getDictData(dictType).then(res => {
        if (res.data.code === 200) {
          let dictList = [];
          if (dictType === 'mall_product_category') {
            dictList.push({
              dictLabel: '推荐',
              dictValue: '-1'
            });
            dictList.push(...res.data.data);
          } else {
            dictList = res.data.data;
          }

          dictData[dictType] = dictList;
          updateDictCache(dictType, dictList);
          delete dictCache.loading[dictType];

          return {
            dictType,
            dictList,
            success: true
          };
        } else {
          console.error(`获取字典[${dictType}]数据失败:`, res.data.msg);
          delete dictCache.loading[dictType];
          return {
            dictType,
            dictList: [],
            success: false,
            msg: res.data.msg
          };
        }
      }).catch(err => {
        console.error(`获取字典[${dictType}]异常:`, err);
        delete dictCache.loading[dictType];
        return {
          dictType,
          dictList: [],
          success: false,
          msg: err
        };
      });
    });

    // 等所有请求完成
    return Promise.allSettled(requests).then(results => {
      const dictMap = {};
      const failed = [];

      results.forEach(r => {
        if (r.status === 'fulfilled') {
          const { dictType, dictList, success, msg } = r.value;
          if (success) {
            dictMap[dictType] = dictList;
          } else {
            failed.push({ dictType, msg });
          }
        } else {
          console.error(`字典请求失败:`, r.reason);
        }
      });

      console.log(`[useDict] Loaded ${Object.keys(dictMap).length} dictionaries, failed ${failed.length}`);

      if (failed.length > 0) {
        console.warn('以下字典加载失败:', failed);
      }

      return dictMap;
    });
  };

  /**
   * 加载字典数据
   * @param {Array} dictTypes - 字典类型数组，如果不传则使用初始化时的dictTypeList
   * @returns {Promise} - 返回字典加载的Promise对象
   */
  const loadDict = (dictTypes) => {
    const types = dictTypes || dictTypeList.value;
    if (!types || types.length === 0) {
      return Promise.resolve({});
    }

    // 标记加载中
    dictLoading.value = true;

    // 需要从服务器获取的字典类型
    const needFetch = [];

    // 检查是否有静态字典或缓存
    types.forEach(type => {
      // 先检查是否有静态字典
      if (staticDict[type]) {
        // 使用静态字典数据
        console.log(`[useDict] Using static dictionary for ${type}`);
        dictData[type] = staticDict[type];
      } else {
        // 检查缓存
        const cachedDict = getDictFromCache(type);
        if (cachedDict) {
          // 已有缓存，直接使用
          console.log(`[useDict] Using cached dictionary for ${type}`);
          dictData[type] = cachedDict;
        } else if (!dictCache.loading[type]) {
          // 需要从服务器获取，并且当前没有其他组件正在加载
          console.log(`[useDict] Need to fetch dictionary ${type} from server`);
          needFetch.push(type);
        } else {
          console.log(`[useDict] Dictionary ${type} is already being loaded by another component, waiting...`);
        }
      }
    });

    // 如果所有字典都已缓存或使用静态数据，直接返回
    if (needFetch.length === 0) {
      dictLoading.value = false;

      // 检查是否有正在加载的字典，如果有，等待它们完成
      const loadingTypes = types.filter(type => dictCache.loading[type]);
      if (loadingTypes.length > 0) {
        return waitForDictLoading(loadingTypes);
      }

      return Promise.resolve(dictData);
    }

    // 从服务器获取字典数据
    return fetchDictData(needFetch).then(res => {
      dictLoading.value = false;
      console.log("dictData", dictData);
      return dictData;
    }).catch(err => {
      dictLoading.value = false;
      console.error('加载字典数据失败:', err);
      return Promise.reject(err);
    });
  };

  /**
   * 清除字典缓存
   * @param {String} dictType - 字典类型，不传则清除所有缓存
   */
  const clearDictCache = (dictType) => {
    if (dictType) {
      delete dictCache.data[dictType];
      delete dictCache.lastUpdateTime[dictType];
      storage.removeDict(`dict_time_${dictType}`);
    } else {
      dictCache.data = {};
      dictCache.lastUpdateTime = {};
      // 清除所有字典相关的本地存储
      // TODO: 需要根据平台使用不同的方式获取所有存储的key
      // 原因: uni-app 没有直接获取所有key的API，需要手动管理字典key列表
      // 推荐: 维护一个字典key列表，在添加字典时记录key，清除时遍历列表删除
    }
  };

  /**
   * 根据字典值获取对应的字典标签
   * @param {String} dictType - 字典类型
   * @param {String|Number} value - 字典值
   * @param {String} defaultLabel - 默认标签
   * @returns {String} - 字典标签
   */
  const getDictLabel = (dictType, value, defaultLabel = '') => {
    // 首先检查组件数据
    const dictList = dictData[dictType];
    if (dictList) {
      const item = dictList.find(dict => dict.dictValue === value);
      if (item) return item.dictLabel;
    }

    // 都没找到，返回默认值
    return defaultLabel;
  };

  /**
   * 根据字典标签获取对应的字典值
   * @param {String} dictType - 字典类型
   * @param {String} label - 字典标签
   * @param {String|Number} defaultValue - 默认值
   * @returns {String|Number} - 字典值
   */
  const getDictValue = (dictType, label, defaultValue = '') => {
    // 首先检查组件数据
    const dictList = dictData[dictType];
    if (dictList) {
      const item = dictList.find(dict => dict.label === label);
      if (item) return item.value;
    }

    // 再检查静态字典
    const staticDictList = staticDict[dictType];
    if (staticDictList) {
      const item = staticDictList.find(dict => dict.label === label);
      if (item) return item.value;
    }

    // 都没找到，返回默认值
    return defaultValue;
  };

  /**
   * 获取字典列表
   * @param {String} dictType - 字典类型
   * @returns {Array} - 字典列表
   */
  const getDictList = (dictType) => {
    // 首先检查组件数据
    const dictList = dictData[dictType];
    if (dictList) return dictList;

    // 再检查静态字典
    return staticDict[dictType] || [];
  };

  /**
   * 获取字典类型对应的样式类
   * @param {String} dictType - 字典类型
   * @param {String|Number} value - 字典值
   * @param {String} defaultClass - 默认样式类
   * @returns {String} - 字典项的样式类
   */
  const getDictClass = (dictType, value, defaultClass = '') => {
    // 首先检查组件数据
    const dictList = dictData[dictType];
    if (dictList) {
      const item = dictList.find(dict => dict.dictValue === value);
      if (item && item.listClass) return item.listClass;
    }

    // 都没找到，返回默认值
    return defaultClass;
  };

  // 自动加载字典
  if (autoLoad && initialDictTypes.length > 0) {
    onMounted(() => {
      console.log(`[useDict] Auto-loading dictionaries: ${initialDictTypes.join(', ')}`);
      loadDict();
    });
  }

  return {
    dictData,
    dictLoading,
    dictTypeList,
    loadDict,
    clearDictCache,
    getDictLabel,
    getDictValue,
    getDictList,
    getDictClass
  };
}

export default useDict;
