/**
 * 从 zhibo 导出的 world-cup-group-stage-matches.json 生成 seed 用裁剪 JSON 与球队映射 TS。
 * 用法: node apps/api/scripts/build-wc2026-seed-json.mjs <源JSON路径>
 */
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const apiRoot = path.resolve(__dirname, '..');
const seedDataDir = path.join(apiRoot, 'src/infrastructure/database/seed-data');
const outrightTeamsPath = path.join(apiRoot, 'src/domains/catalog/wc2026-outright-teams.ts');

const sourcePath = process.argv[2];
if (!sourcePath) {
  console.error('用法: node build-wc2026-seed-json.mjs <源JSON路径>');
  process.exit(1);
}

const raw = JSON.parse(fs.readFileSync(path.resolve(sourcePath), 'utf8'));
const outrightSrc = fs.readFileSync(outrightTeamsPath, 'utf8');
const outrightTeams = [...outrightSrc.matchAll(/code: '([^']+)', names: \{ 'zh-CN': '([^']+)', 'en-US': '([^']+)'/g)].map((m) => ({
  code: m[1],
  zh: m[2],
  en: m[3],
}));

const CODE_TO_FLAG_ISO = {
  ALG: 'dz',
  ARG: 'ar',
  AUS: 'au',
  AUT: 'at',
  BEL: 'be',
  BIH: 'ba',
  BRA: 'br',
  CAN: 'ca',
  CIV: 'ci',
  COD: 'cd',
  COL: 'co',
  CPV: 'cv',
  CRO: 'hr',
  CUW: 'cw',
  CZE: 'cz',
  ECU: 'ec',
  EGY: 'eg',
  ENG: 'gb-eng',
  ESP: 'es',
  FRA: 'fr',
  GER: 'de',
  GHA: 'gh',
  HAI: 'ht',
  IRN: 'ir',
  IRQ: 'iq',
  JOR: 'jo',
  JPN: 'jp',
  KOR: 'kr',
  KSA: 'sa',
  MAR: 'ma',
  MEX: 'mx',
  NED: 'nl',
  NOR: 'no',
  NZL: 'nz',
  PAN: 'pa',
  PAR: 'py',
  POR: 'pt',
  QAT: 'qa',
  RSA: 'za',
  SCO: 'gb-sct',
  SEN: 'sn',
  SUI: 'ch',
  SWE: 'se',
  TUN: 'tn',
  TUR: 'tr',
  URU: 'uy',
  USA: 'us',
  UZB: 'uz',
};

function flagUrlForCode(code) {
  const iso = CODE_TO_FLAG_ISO[code];
  return iso ? `https://flagcdn.com/${iso}.svg` : '';
}

function pickNames(names) {
  return {
    zh: names?.zh ?? null,
    en: names?.en ?? null,
    zhTw: names?.zhTw ?? null,
    vi: names?.vi ?? null,
    km: names?.km ?? null,
    ms: names?.ms ?? null,
  };
}

function pickTeam(team) {
  const code = resolveCanonicalCode(team);
  return {
    id: team.id,
    name: team.name,
    names: pickNames(team.names),
    image: code ? flagUrlForCode(code) : '',
  };
}

function slimMatch(m) {
  return {
    officialMatchNo: m.officialMatchNo,
    stage: m.stage,
    groupName: m.groupName,
    liveMatchId: m.liveMatchId,
    additionMatchId: m.additionMatchId,
    channelId: m.channelId,
    matchName: m.matchName,
    league: { type: m.league.type, en: m.league.en, zh: m.league.zh },
    kickoff: {
      utcTimeStart: m.kickoff.utcTimeStart,
      utcTimeStop: m.kickoff.utcTimeStop,
      utcIso: m.kickoff.utcIso,
      chinaTime: m.kickoff.chinaTime,
      venueTime: m.kickoff.venueTime,
      venueTimezone: m.kickoff.venueTimezone,
    },
    homeTeam: pickTeam(m.homeTeam),
    awayTeam: pickTeam(m.awayTeam),
    status: { state: m.status.state, isHot: 0 },
    venue: {
      names: pickNames(m.venue?.names),
      city: pickNames(m.venue?.city),
    },
    sortOrder: m.sortOrder,
    isPublished: m.isPublished,
  };
}

function resolveCanonicalCode(team) {
  const en = (team.name || team.names?.en || '').toLowerCase();
  const zh = team.names?.zh || '';
  const hit = outrightTeams.find(
    (o) =>
      o.en.toLowerCase() === en ||
      o.zh === zh ||
      (o.en === 'Turkey' && en.includes('türkiye')) ||
      (o.en === 'Czech' && en === 'czechia') ||
      (o.en === 'Bosnia' && en.includes('bosnia')) ||
      (o.en === 'Ivory Coast' && en.includes('côte')) ||
      (o.en === 'DR Congo' && en.includes('congo')) ||
      (o.en === 'Curacao' && en.includes('cura')),
  );
  return hit?.code ?? null;
}

const matches = (raw.matches || []).map(slimMatch);
const bundle = { count: matches.length, matches };

const teamById = new Map();
for (const m of raw.matches || []) {
  for (const t of [m.homeTeam, m.awayTeam]) {
    if (t?.id != null) teamById.set(t.id, t);
  }
}

const zhiboToCode = {};
const unmatched = [];
const missingFlagCodes = new Set();
for (const [id, team] of teamById) {
  const code = resolveCanonicalCode(team);
  if (code) {
    zhiboToCode[id] = code;
    const flagUrl = flagUrlForCode(code);
    if (!flagUrl) {
      missingFlagCodes.add(code);
    }
  } else {
    unmatched.push({ id, name: team.name });
  }
}

fs.mkdirSync(seedDataDir, { recursive: true });
const jsonOut = path.join(seedDataDir, 'wc2026-group-stage.json');
fs.writeFileSync(jsonOut, JSON.stringify(bundle, null, 2) + '\n', 'utf8');

const mapLines = Object.entries(zhiboToCode)
  .sort(([a], [b]) => Number(a) - Number(b))
  .map(([id, code]) => `  ${id}: '${code}',`)
  .join('\n');

const flagIsoLines = Object.entries(CODE_TO_FLAG_ISO)
  .sort(([a], [b]) => a.localeCompare(b))
  .map(([code, iso]) => `  ${code}: '${iso}',`)
  .join('\n');

const mapTs = `/** 由 build-wc2026-seed-json.mjs 生成 — zhibo externalId → WC2026 canonical code */
export const WC2026_ZIBO_ID_TO_CODE: Record<number, string> = {
${mapLines}
};

/** WC2026 默认国家/地区国旗（FlagCDN，seed 时写入 teams.logo_url） */
export const WC2026_FLAG_ISO_BY_CODE: Record<string, string> = {
${flagIsoLines}
};

export const WC2026_TEAM_LOGO_BY_CODE: Record<string, string> = Object.fromEntries(
  Object.entries(WC2026_FLAG_ISO_BY_CODE).map(([code, iso]) => [
    code,
    \`https://flagcdn.com/\${iso}.svg\`,
  ]),
);
`;

const mapOut = path.join(seedDataDir, 'wc2026-zhibo-team-map.ts');
fs.writeFileSync(mapOut, mapTs, 'utf8');

console.log(`Wrote ${jsonOut} (${matches.length} matches)`);
console.log(`Wrote ${mapOut} (${Object.keys(zhiboToCode).length} team mappings)`);
if (unmatched.length) {
  console.warn('Unmatched teams:', unmatched);
  process.exit(1);
}
if (missingFlagCodes.size) {
  console.warn('Missing FlagCDN ISO mapping:', [...missingFlagCodes].sort());
  process.exit(1);
}
