/**
 * 型号关联字典 — 对已知"型号即定产品"的特殊物料，
 * 在 LLM 标准化结果返回后做后处理覆盖，
 * 强制 outcome=success 并注入正确的 suggested_keyword。
 *
 * 其余标准化字段（材质、用途等）仍由 LLM 填写。
 */

export interface ModelOverrideEntry {
  /** 注入到标准化结果的 suggested_keyword */
  suggested_keyword: string;
  /** 备注（仅文档用途，不写入结果） */
  note: string;
}

/**
 * 型号 → 覆盖条目。Key 统一大写，匹配时忽略大小写。
 * 新增型号只需在此处追加即可。
 * 注意：运行时从 DB 加载的字典（runtimeOverrides）优先级高于此静态字典。
 */
const MODEL_NUMBER_OVERRIDES: Record<string, ModelOverrideEntry> = {
  GEB371: {
    suggested_keyword: "GEB371外挂电池",
    note: "徕卡全站仪专用外挂电池",
  },
};

/** 运行时字典：由自动化服务在每次任务启动前从 DB 加载，优先级高于静态字典 */
let runtimeOverrides: Record<string, ModelOverrideEntry> = {};

/**
 * 注入从 DB 加载的字典，在标准化任务启动前调用。
 * DB 条目会覆盖静态字典中同名型号。
 */
export function setRuntimeModelOverrides(overrides: Record<string, ModelOverrideEntry>): void {
  runtimeOverrides = overrides;
}

export function mergeRuntimeModelOverrides(overrides: Record<string, ModelOverrideEntry>): void {
  runtimeOverrides = { ...runtimeOverrides, ...overrides };
}

/** 预编译正则缓存 */
const overrideRegexCache = new Map<string, RegExp>();

function getOverrideRegex(model: string): RegExp {
  let re = overrideRegexCache.get(model);
  if (!re) {
    // 使用词边界防止部分匹配（如 LGEB3710 不应命中 GEB371）
    re = new RegExp(`\\b${model.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, "i");
    overrideRegexCache.set(model, re);
  }
  return re;
}

interface OverridableResult {
  outcome: string;
  can_search_1688: boolean;
  suggested_keyword: string;
  missing_required_fields: string[];
  failure_reason: string;
  human_fix_hint: string;
}

/**
 * 检查规格/名称文本是否命中已知型号，
 * 命中时覆盖 outcome 相关字段为 success，其余字段不变。
 *
 * @param textToMatch - 待匹配文本（通常拼接 名称 + 规格型号）
 * @param result - LLM 输出的标准化结果
 * @returns 覆盖后的结果（命中时返回新对象，未命中返回原对象）
 */
export function applyModelNumberOverride<T extends OverridableResult>(
  textToMatch: string,
  result: T,
): T {
  if (!textToMatch) return result;

  // 合并字典：DB 加载的 runtimeOverrides 优先级高于静态字典
  const merged: Record<string, ModelOverrideEntry> = { ...MODEL_NUMBER_OVERRIDES, ...runtimeOverrides };

  for (const [model, entry] of Object.entries(merged)) {
    if (getOverrideRegex(model).test(textToMatch)) {
      return {
        ...result,
        outcome: "success",
        can_search_1688: true,
        suggested_keyword: entry.suggested_keyword,
        missing_required_fields: [],
        failure_reason: "",
        human_fix_hint: "",
      };
    }
  }

  return result;
}
