/**
 * 根据运单号前缀推断快递公司（用于发货表单自动选中）
 * 匹配关键字同时支持公司名与 code（如 shunfeng）
 */

export type ExpressMatchOption = {
  id?: number;
  name?: string;
  code?: string;
};

/** 常见单号前缀 → 公司名 / code 关键字（按前缀长度降序匹配，避免短前缀误伤） */
const PREFIX_RULES: Array<{ prefixes: string[]; keywords: string[] }> = [
  { prefixes: ['SF'], keywords: ['顺丰', 'shunfeng', 'sf'] },
  { prefixes: ['ZTO', 'ZT'], keywords: ['中通', 'zhongtong', 'zto'] },
  { prefixes: ['STO'], keywords: ['申通', 'shentong', 'sto'] },
  { prefixes: ['YTO', 'YT'], keywords: ['圆通', 'yuantong', 'yto'] },
  { prefixes: ['YD'], keywords: ['韵达', 'yunda', 'yd'] },
  { prefixes: ['JD'], keywords: ['京东', 'jd', 'jingdong'] },
  { prefixes: ['JT'], keywords: ['极兔', 'jitu', 'jt'] },
  { prefixes: ['EMS', 'E'], keywords: ['ems', '邮政'] },
  { prefixes: ['HHTT', 'HT'], keywords: ['百世', 'baishi', 'huitong'] },
  { prefixes: ['UC'], keywords: ['优速', 'uc'] },
  { prefixes: ['DBL'], keywords: ['德邦', 'debang', 'dbl'] },
];

/**
 * 按运单号前缀在 options 中找最可能的快递公司
 * @returns 匹配到的 option，未匹配返回 null
 */
export function matchExpressByTrackingNo(
  trackingNo: string | undefined | null,
  options: ExpressMatchOption[],
): ExpressMatchOption | null {
  const no = String(trackingNo || '')
    .trim()
    .toUpperCase()
    .replace(/\s+/g, '');
  if (!no || !Array.isArray(options) || !options.length) {
    return null;
  }
  const sortedRules = [...PREFIX_RULES].sort(
    (a, b) =>
      Math.max(...b.prefixes.map((p) => p.length)) -
      Math.max(...a.prefixes.map((p) => p.length)),
  );
  let matchedKeywords: string[] | null = null;
  for (const rule of sortedRules) {
    if (rule.prefixes.some((p) => no.startsWith(p))) {
      matchedKeywords = rule.keywords;
      break;
    }
  }
  if (!matchedKeywords) {
    return null;
  }
  const keywords = matchedKeywords.map((k) => k.toLowerCase());
  for (const opt of options) {
    const name = String(opt.name || '').toLowerCase();
    const code = String(opt.code || '').toLowerCase();
    if (keywords.some((k) => name.includes(k) || code === k || code.includes(k))) {
      return opt;
    }
  }
  return null;
}
