import { code_msg } from "../utils/constants.js";
import axios from "axios";
import config from '../config/config.js';

// 类型定义
type ErrorCode = string | number;  // 错误码可以是字符串或数字
type ErrorMessage = string;       // 错误信息字符串
type ErrorCodeMap = Map<ErrorCode, ErrorMessage>;  // 错误码映射表结构
type ErrorCodeObject = Record<string, ErrorMessage>;  // 普通对象形式的错误码集合

// 配置选项接口
interface GetAllCodesOptions {
  mode?: 'static' | 'dynamic';  // 模式选择：static-静态模式，dynamic-动态模式
  reload?: boolean;             // 是否强制重新加载
}

// API响应数据结构
interface ApiResponse {
  errorCode: number;           // 接口返回的状态码
  errorMsg: string;            // 接口返回的错误信息
  result: {
    codes?: ErrorCodeObject;    // 动态错误码数据
  };
}

// 初始化存储结构
const errorCodeMap: ErrorCodeMap = new Map(code_msg as any);  // 静态错误码存储
const codesMap: ErrorCodeMap = new Map();              // 动态错误码存储

// -------------------------------------- Static Error Codes (本地固定错误码) ----------------------------

/**
 * 删除静态错误码
 * @param code 要删除的错误码
 */
const removeStaticCode = (code: ErrorCode): void => {
  errorCodeMap.delete(code);
};

/**
 * 添加静态错误码
 * @param code 错误码
 * @param msg 错误信息（可选）
 */
const addStaticCode = (code: ErrorCode, msg: ErrorMessage = ''): void => {
  errorCodeMap.set(code, msg);
};

/**
 * 获取静态错误码信息
 * @param code 要查询的错误码
 * @returns 对应的错误信息，未找到返回undefined
 */
const getStaticCode = (code: ErrorCode): ErrorMessage | undefined => {
  return errorCodeMap.get(code);
};

/**
 * 检查静态错误码是否存在
 * @param code 要检查的错误码
 * @returns 是否存在布尔值
 */
const hasStaticCode = (code: ErrorCode): boolean => {
  return errorCodeMap.has(code);
};

/**
 * 获取所有静态错误码
 * @returns 返回完整的静态错误码Map
 */
const getAllStaticCode = (): ErrorCodeMap => {
  return errorCodeMap;
};

/**
 * 设置/更新静态错误码
 * @param code 要设置的错误码
 * @param msg 要设置的错误信息（可选）
 */
const setStaticCode = (code: ErrorCode, msg: ErrorMessage = ''): void => {
  errorCodeMap.set(code, msg);
};

/**
 * 获取对象形式的静态错误码集合
 * @returns 普通对象形式的错误码集合
 */
const errorStaticCodeObject = (): ErrorCodeObject => {
  return Object.fromEntries(errorCodeMap);
};

// -------------------------------------- Dynamic Error Codes (API获取的错误码) ---------------------

/**
 * 删除动态错误码
 * @param code 要删除的错误码
 */
const removeDynamicCode = (code: ErrorCode): void => {
  codesMap.delete(code);
};

/**
 * 添加动态错误码
 * @param code 错误码
 * @param msg 错误信息（可选）
 */
const addDynamicCode = (code: ErrorCode, msg: ErrorMessage = ''): void => {
  codesMap.set(code, msg);
};

/**
 * 获取动态错误码信息
 * @param code 要查询的错误码
 * @returns 对应的错误信息，未找到返回undefined
 */
const getDynamicCode = (code: ErrorCode): ErrorMessage | undefined => {
  return codesMap.get(code);
};

/**
 * 检查动态错误码是否存在
 * @param code 要检查的错误码
 * @returns 是否存在布尔值
 */
const hasDynamicCode = (code: ErrorCode): boolean => {
  return codesMap.has(code);
};

/**
 * 获取所有动态错误码
 * @returns 返回完整的动态错误码Map
 */
const getAllDynamicCode = (): ErrorCodeMap => {
  return codesMap;
};

/**
 * 设置/更新动态错误码
 * @param code 要设置的错误码
 * @param msg 要设置的错误信息（可选）
 */
const setDynamicCode = (code: ErrorCode, msg: ErrorMessage = ''): void => {
  codesMap.set(code, msg);
};

/**
 * 获取对象形式的动态错误码集合
 * @returns 普通对象形式的错误码集合
 */
const errorDynamicCodeObject = (): ErrorCodeObject => {
  return Object.fromEntries(codesMap);
};

/**
 * 获取所有错误码的主方法
 * @param options 配置选项
 * @param options.mode 模式选择，默认'dynamic'
 * @param options.reload 是否强制重新加载，默认false
 * @returns 返回错误码集合或null(出错时)
 * 
 * 静态模式：直接返回本地存储的错误码
 * 动态模式：从API获取错误码并缓存
 */
const getAllcodes = async (
  { mode = 'dynamic', reload = false }: GetAllCodesOptions = {}
): Promise<ErrorCodeMap | ErrorCodeObject | null> => {

  // 静态模式直接返回
  if (mode === 'static') {
    return errorStaticCodeObject();
  }

  // 动态模式：检查缓存是否需要更新
  if (codesMap.size !== 0 && !reload) {
    return codesMap;
  }

  // 从API动态加载错误码
  try {
    const response: ApiResponse = await axios.post(config.address, {}, {
      headers: {
        'Content-Type': 'application/json'
      }
    });

    const { errorCode, errorMsg, result } = response;

    // 验证接口返回状态
    if (errorCode !== 0) {
      console.error('动态接口错误：请检查接口路径！', errorMsg);
      return null;
    }

    // 处理返回的错误码数据
    if (result.codes) {
      Object.entries(result.codes).forEach(([key, value]) => {
        codesMap.set(key, value);
      });
    }
    return codesMap;
  } catch (error) {
    console.error('代码执行错误：', error instanceof Error ? error.message : error);
    return null;
  }
};

// 导出所有方法
export {
  removeStaticCode,
  addStaticCode,
  getStaticCode,
  hasStaticCode,
  getAllStaticCode,
  setStaticCode,
  errorStaticCodeObject,
  removeDynamicCode,
  addDynamicCode,
  getDynamicCode,
  hasDynamicCode,
  getAllDynamicCode,
  setDynamicCode,
  errorDynamicCodeObject,
  getAllcodes
};