import COMTRADE_REPORTER_OVERRIDES from '../../scripts/shared/comtrade-reporter-overrides.json';

export const ISO2_TO_ISO3: Record<string, string> = {
  AD: 'AND', AE: 'ARE', AF: 'AFG', AG: 'ATG', AI: 'AIA', AL: 'ALB', AM: 'ARM', AO: 'AGO',
  AQ: 'ATA', AR: 'ARG', AS: 'ASM', AT: 'AUT', AU: 'AUS', AW: 'ABW', AX: 'ALA', AZ: 'AZE',
  BA: 'BIH', BB: 'BRB', BD: 'BGD', BE: 'BEL', BF: 'BFA', BG: 'BGR', BH: 'BHR', BI: 'BDI',
  BJ: 'BEN', BL: 'BLM', BM: 'BMU', BN: 'BRN', BO: 'BOL', BR: 'BRA', BS: 'BHS', BT: 'BTN',
  BW: 'BWA', BY: 'BLR', BZ: 'BLZ', CA: 'CAN', CD: 'COD', CF: 'CAF', CG: 'COG', CH: 'CHE',
  CI: 'CIV', CK: 'COK', CL: 'CHL', CM: 'CMR', CN: 'CHN', CO: 'COL', CR: 'CRI', CU: 'CUB',
  CV: 'CPV', CW: 'CUW', CY: 'CYP', CZ: 'CZE', DE: 'DEU', DJ: 'DJI', DK: 'DNK', DM: 'DMA',
  DO: 'DOM', DZ: 'DZA', EC: 'ECU', EE: 'EST', EG: 'EGY', EH: 'ESH', ER: 'ERI', ES: 'ESP',
  ET: 'ETH', FI: 'FIN', FJ: 'FJI', FK: 'FLK', FM: 'FSM', FO: 'FRO', FR: 'FRA', GA: 'GAB',
  GB: 'GBR', GD: 'GRD', GE: 'GEO', GG: 'GGY', GH: 'GHA', GI: 'GIB', GL: 'GRL', GM: 'GMB',
  GN: 'GIN', GQ: 'GNQ', GR: 'GRC', GS: 'SGS', GT: 'GTM', GU: 'GUM', GW: 'GNB', GY: 'GUY',
  HK: 'HKG', HM: 'HMD', HN: 'HND', HR: 'HRV', HT: 'HTI', HU: 'HUN', ID: 'IDN', IE: 'IRL',
  IL: 'ISR', IM: 'IMN', IN: 'IND', IO: 'IOT', IQ: 'IRQ', IR: 'IRN', IS: 'ISL', IT: 'ITA',
  JE: 'JEY', JM: 'JAM', JO: 'JOR', JP: 'JPN', KE: 'KEN', KG: 'KGZ', KH: 'KHM', KI: 'KIR',
  KM: 'COM', KN: 'KNA', KP: 'PRK', KR: 'KOR', KW: 'KWT', KY: 'CYM', KZ: 'KAZ', LA: 'LAO',
  LB: 'LBN', LC: 'LCA', LI: 'LIE', LK: 'LKA', LR: 'LBR', LS: 'LSO', LT: 'LTU', LU: 'LUX',
  LV: 'LVA', LY: 'LBY', MA: 'MAR', MC: 'MCO', MD: 'MDA', ME: 'MNE', MF: 'MAF', MG: 'MDG',
  MH: 'MHL', MK: 'MKD', ML: 'MLI', MM: 'MMR', MN: 'MNG', MO: 'MAC', MP: 'MNP', MR: 'MRT',
  MS: 'MSR', MT: 'MLT', MU: 'MUS', MV: 'MDV', MW: 'MWI', MX: 'MEX', MY: 'MYS', MZ: 'MOZ',
  NA: 'NAM', NC: 'NCL', NE: 'NER', NF: 'NFK', NG: 'NGA', NI: 'NIC', NL: 'NLD', NO: 'NOR',
  NP: 'NPL', NR: 'NRU', NU: 'NIU', NZ: 'NZL', OM: 'OMN', PA: 'PAN', PE: 'PER', PF: 'PYF',
  PG: 'PNG', PH: 'PHL', PK: 'PAK', PL: 'POL', PM: 'SPM', PN: 'PCN', PR: 'PRI', PS: 'PSE',
  PT: 'PRT', PW: 'PLW', PY: 'PRY', QA: 'QAT', RO: 'ROU', RS: 'SRB', RU: 'RUS', RW: 'RWA',
  SA: 'SAU', SB: 'SLB', SC: 'SYC', SD: 'SDN', SE: 'SWE', SG: 'SGP', SH: 'SHN', SI: 'SVN',
  SK: 'SVK', SL: 'SLE', SM: 'SMR', SN: 'SEN', SO: 'SOM', SR: 'SUR', SS: 'SSD', ST: 'STP',
  SV: 'SLV', SX: 'SXM', SY: 'SYR', SZ: 'SWZ', TC: 'TCA', TD: 'TCD', TF: 'ATF', TG: 'TGO',
  TH: 'THA', TJ: 'TJK', TL: 'TLS', TM: 'TKM', TN: 'TUN', TO: 'TON', TR: 'TUR', TT: 'TTO',
  TV: 'TUV', TW: 'TWN', TZ: 'TZA', UA: 'UKR', UG: 'UGA', UM: 'UMI', US: 'USA', UY: 'URY',
  UZ: 'UZB', VA: 'VAT', VC: 'VCT', VE: 'VEN', VG: 'VGB', VI: 'VIR', VN: 'VNM', VU: 'VUT',
  WF: 'WLF', WS: 'WSM', XK: 'XKX', YE: 'YEM', ZA: 'ZAF', ZM: 'ZMB', ZW: 'ZWE',
};

const ISO2_TO_UN: Record<string, string> = {
  AD: '020', AE: '784', AF: '004', AG: '028', AI: '660', AL: '008', AM: '051', AO: '024',
  AQ: '010', AR: '032', AS: '016', AT: '040', AU: '036', AW: '533', AX: '248', AZ: '031',
  BA: '070', BB: '052', BD: '050', BE: '056', BF: '854', BG: '100', BH: '048', BI: '108',
  BJ: '204', BL: '652', BM: '060', BN: '096', BO: '068', BR: '076', BS: '044', BT: '064',
  BW: '072', BY: '112', BZ: '084', CA: '124', CD: '180', CF: '140', CG: '178', CH: '756',
  CI: '384', CK: '184', CL: '152', CM: '120', CN: '156', CO: '170', CR: '188', CU: '192',
  CV: '132', CW: '531', CY: '196', CZ: '203', DE: '276', DJ: '262', DK: '208', DM: '212',
  DO: '214', DZ: '012', EC: '218', EE: '233', EG: '818', EH: '732', ER: '232', ES: '724',
  ET: '231', FI: '246', FJ: '242', FK: '238', FM: '583', FO: '234', FR: '250', GA: '266',
  GB: '826', GD: '308', GE: '268', GG: '831', GH: '288', GI: '292', GL: '304', GM: '270',
  GN: '324', GQ: '226', GR: '300', GS: '239', GT: '320', GU: '316', GW: '624', GY: '328',
  HK: '344', HM: '334', HN: '340', HR: '191', HT: '332', HU: '348', ID: '360', IE: '372',
  IL: '376', IM: '833', IN: '356', IO: '086', IQ: '368', IR: '364', IS: '352', IT: '380',
  JE: '832', JM: '388', JO: '400', JP: '392', KE: '404', KG: '417', KH: '116', KI: '296',
  KM: '174', KN: '659', KP: '408', KR: '410', KW: '414', KY: '136', KZ: '398', LA: '418',
  LB: '422', LC: '662', LI: '438', LK: '144', LR: '430', LS: '426', LT: '440', LU: '442',
  LV: '428', LY: '434', MA: '504', MC: '492', MD: '498', ME: '499', MF: '663', MG: '450',
  MH: '584', MK: '807', ML: '466', MM: '104', MN: '496', MO: '446', MP: '580', MR: '478',
  MS: '500', MT: '470', MU: '480', MV: '462', MW: '454', MX: '484', MY: '458', MZ: '508',
  NA: '516', NC: '540', NE: '562', NF: '574', NG: '566', NI: '558', NL: '528', NO: '578',
  NP: '524', NR: '520', NU: '570', NZ: '554', OM: '512', PA: '591', PE: '604', PF: '258',
  PG: '598', PH: '608', PK: '586', PL: '616', PM: '666', PN: '612', PR: '630', PS: '275',
  PT: '620', PW: '585', PY: '600', QA: '634', RO: '642', RS: '688', RU: '643', RW: '646',
  SA: '682', SB: '090', SC: '690', SD: '729', SE: '752', SG: '702', SH: '654', SI: '705',
  SK: '703', SL: '694', SM: '674', SN: '686', SO: '706', SR: '740', SS: '728', ST: '678',
  SV: '222', SX: '534', SY: '760', SZ: '748', TC: '796', TD: '148', TF: '260', TG: '768',
  TH: '764', TJ: '762', TL: '626', TM: '795', TN: '788', TO: '776', TR: '792', TT: '780',
  TV: '798', TW: '158', TZ: '834', UA: '804', UG: '800', UM: '581', US: '840', UY: '858',
  UZ: '860', VA: '336', VC: '670', VE: '862', VG: '092', VI: '850', VN: '704', VU: '548',
  WF: '876', WS: '882', XK: '412', YE: '887', ZA: '710', ZM: '894', ZW: '716',
};

export function iso2ToIso3(iso2: string): string | null {
  return ISO2_TO_ISO3[iso2.toUpperCase()] ?? null;
}

export function iso2ToUnCode(iso2: string): string | null {
  return ISO2_TO_UN[iso2.toUpperCase()] ?? null;
}

// UN M49 codes mostly match UN Comtrade reporterCodes. Use the shared override
// file wherever an iso2 feeds into a Comtrade reporterCode lookup or seeded
// comtrade:* key so non-M49 reporters stay aligned with server/seed paths.
const ISO2_TO_COMTRADE_OVERRIDES: Readonly<Record<string, string>> = COMTRADE_REPORTER_OVERRIDES;
export function iso2ToComtradeReporterCode(iso2: string): string | null {
  const upper = iso2.toUpperCase();
  return ISO2_TO_COMTRADE_OVERRIDES[upper] ?? ISO2_TO_UN[upper] ?? null;
}

const ISO3_TO_ISO2: Record<string, string> = Object.fromEntries(
  Object.entries(ISO2_TO_ISO3).map(([iso2, iso3]) => [iso3, iso2]),
);

// Tight alias map for the most common name forms. Keep <30 entries; reject
// unknown rather than try to be a full geocoder. Keys are lowercase.
const NAME_ALIASES_TO_ISO2: Record<string, string> = {
  'united states': 'US',
  'united states of america': 'US',
  'usa': 'US',
  'u.s.': 'US',
  'u.s.a.': 'US',
  'america': 'US',
  'united kingdom': 'GB',
  'uk': 'GB',
  'u.k.': 'GB',
  'britain': 'GB',
  'great britain': 'GB',
  'england': 'GB',
  'russia': 'RU',
  'russian federation': 'RU',
  'south korea': 'KR',
  'korea, south': 'KR',
  'republic of korea': 'KR',
  'north korea': 'KP',
  'korea, north': 'KP',
  'czech republic': 'CZ',
  'czechia': 'CZ',
  'ivory coast': 'CI',
  "cote d'ivoire": 'CI',
  'vietnam': 'VN',
  'viet nam': 'VN',
  'iran': 'IR',
  'syria': 'SY',
  'taiwan': 'TW',
  'palestine': 'PS',
  'vatican': 'VA',
  'uae': 'AE',
};

export function toIso2(input: string | null | undefined): string | null {
  if (input == null) return null;
  const trimmed = input.trim();
  if (!trimmed) return null;
  const upper = trimmed.toUpperCase();
  if (upper.length === 2 && ISO2_TO_ISO3[upper]) return upper;
  if (upper.length === 3 && ISO3_TO_ISO2[upper]) return ISO3_TO_ISO2[upper];
  return NAME_ALIASES_TO_ISO2[trimmed.toLowerCase()] ?? null;
}
