// gen-flag-positions.js
//
// Reads /tmp/ne_label_points.geojson (Natural Earth's hand-curated
// ne_10m_admin_0_label_points) and emits flag-positions.js — a static lookup
// table that maps each ISO-alpha-2 country code to its cartographer-placed
// label points. The map renderer uses these as flag-stamp anchors.
//
// Each entry: { lon, lat, rank, name }
//   rank = scalerank (lower = more prominent; 0 is the country's primary point)
//   name = sr_subunit (e.g. "Alaska", "Hawaii", "Java", "Sicily")
//
// Filter rules:
//   • Keep scalerank ≤ MAX_RANK so we don't drown the map in tiny islands.
//   • Cap at MAX_POINTS_PER_COUNTRY so visual-noise countries (Canada arctic,
//     Indonesia archipelago) stay legible.
//   • Sorted by rank ascending so the primary label is always entries[0].
//
// Run: node map/scripts/gen-flag-positions.js
// Output: map/data-built/flag-positions.js (loaded by index.html before the bundle)

const fs = require('fs');
const path = require('path');

const MAX_RANK = 4;             // 0..4 includes mainland + major sub-units
const MAX_POINTS_PER_COUNTRY = 10;
const INPUT = '/tmp/ne_label_points.geojson';
const OUTPUT = path.resolve(__dirname, '../../flag-positions.js');

// ISO 3166-1 alpha-3 → alpha-2 (lowercase). Covers every Natural Earth country.
const A3_TO_A2 = {
  AFG:"af",ALB:"al",DZA:"dz",ASM:"as",AND:"ad",AGO:"ao",AIA:"ai",ATA:"aq",ATG:"ag",ARG:"ar",
  ARM:"am",ABW:"aw",AUS:"au",AUT:"at",AZE:"az",BHS:"bs",BHR:"bh",BGD:"bd",BRB:"bb",BLR:"by",
  BEL:"be",BLZ:"bz",BEN:"bj",BMU:"bm",BTN:"bt",BOL:"bo",BES:"bq",BIH:"ba",BWA:"bw",BVT:"bv",
  BRA:"br",IOT:"io",BRN:"bn",BGR:"bg",BFA:"bf",BDI:"bi",CPV:"cv",KHM:"kh",CMR:"cm",CAN:"ca",
  CYM:"ky",CAF:"cf",TCD:"td",CHL:"cl",CHN:"cn",CXR:"cx",CCK:"cc",COL:"co",COM:"km",COD:"cd",
  COG:"cg",COK:"ck",CRI:"cr",CIV:"ci",HRV:"hr",CUB:"cu",CUW:"cw",CYP:"cy",CZE:"cz",DNK:"dk",
  DJI:"dj",DMA:"dm",DOM:"do",ECU:"ec",EGY:"eg",SLV:"sv",GNQ:"gq",ERI:"er",EST:"ee",SWZ:"sz",
  ETH:"et",FLK:"fk",FRO:"fo",FJI:"fj",FIN:"fi",FRA:"fr",GUF:"gf",PYF:"pf",ATF:"tf",GAB:"ga",
  GMB:"gm",GEO:"ge",DEU:"de",GHA:"gh",GIB:"gi",GRC:"gr",GRL:"gl",GRD:"gd",GLP:"gp",GUM:"gu",
  GTM:"gt",GGY:"gg",GIN:"gn",GNB:"gw",GUY:"gy",HTI:"ht",HMD:"hm",VAT:"va",HND:"hn",HKG:"hk",
  HUN:"hu",ISL:"is",IND:"in",IDN:"id",IRN:"ir",IRQ:"iq",IRL:"ie",IMN:"im",ISR:"il",ITA:"it",
  JAM:"jm",JPN:"jp",JEY:"je",JOR:"jo",KAZ:"kz",KEN:"ke",KIR:"ki",PRK:"kp",KOR:"kr",KWT:"kw",
  KGZ:"kg",LAO:"la",LVA:"lv",LBN:"lb",LSO:"ls",LBR:"lr",LBY:"ly",LIE:"li",LTU:"lt",LUX:"lu",
  MAC:"mo",MKD:"mk",MDG:"mg",MWI:"mw",MYS:"my",MDV:"mv",MLI:"ml",MLT:"mt",MHL:"mh",MTQ:"mq",
  MRT:"mr",MUS:"mu",MYT:"yt",MEX:"mx",FSM:"fm",MDA:"md",MCO:"mc",MNG:"mn",MNE:"me",MSR:"ms",
  MAR:"ma",MOZ:"mz",MMR:"mm",NAM:"na",NRU:"nr",NPL:"np",NLD:"nl",NCL:"nc",NZL:"nz",NIC:"ni",
  NER:"ne",NGA:"ng",NIU:"nu",NFK:"nf",MNP:"mp",NOR:"no",OMN:"om",PAK:"pk",PLW:"pw",PSE:"ps",
  PAN:"pa",PNG:"pg",PRY:"py",PER:"pe",PHL:"ph",PCN:"pn",POL:"pl",PRT:"pt",PRI:"pr",QAT:"qa",
  REU:"re",ROU:"ro",RUS:"ru",RWA:"rw",BLM:"bl",SHN:"sh",KNA:"kn",LCA:"lc",MAF:"mf",SPM:"pm",
  VCT:"vc",WSM:"ws",SMR:"sm",STP:"st",SAU:"sa",SEN:"sn",SRB:"rs",SYC:"sc",SLE:"sl",SGP:"sg",
  SXM:"sx",SVK:"sk",SVN:"si",SLB:"sb",SOM:"so",ZAF:"za",SGS:"gs",SSD:"ss",ESP:"es",LKA:"lk",
  SDN:"sd",SUR:"sr",SJM:"sj",SWE:"se",CHE:"ch",SYR:"sy",TWN:"tw",TJK:"tj",TZA:"tz",THA:"th",
  TLS:"tl",TGO:"tg",TKL:"tk",TON:"to",TTO:"tt",TUN:"tn",TUR:"tr",TKM:"tm",TCA:"tc",TUV:"tv",
  UGA:"ug",UKR:"ua",ARE:"ae",GBR:"gb",USA:"us",UMI:"um",URY:"uy",UZB:"uz",VUT:"vu",VEN:"ve",
  VNM:"vn",VGB:"vg",VIR:"vi",WLF:"wf",ESH:"eh",YEM:"ye",ZMB:"zm",ZWE:"zw",
  // Natural Earth uses a few non-standard a3 codes
  KOS:"xk",  // Kosovo
  SDS:"ss",  // South Sudan (older NE code)
  CYN:"cy",  // Northern Cyprus → mapped to Cyprus
  SAH:"eh",  // Western Sahara
};

function main() {
  const raw = fs.readFileSync(INPUT, 'utf8');
  const data = JSON.parse(raw);
  const grouped = new Map();
  let mapped = 0, skippedRank = 0, skippedIso = 0;

  for (const f of data.features) {
    const p = f.properties;
    if (typeof p.scalerank !== 'number' || p.scalerank > MAX_RANK) { skippedRank++; continue; }
    const a3 = p.sr_adm0_a3;
    const iso = A3_TO_A2[a3];
    if (!iso) { skippedIso++; continue; }
    const [lon, lat] = f.geometry.coordinates;
    if (!Number.isFinite(lon) || !Number.isFinite(lat)) continue;
    if (!grouped.has(iso)) grouped.set(iso, []);
    grouped.get(iso).push({
      lon: +lon.toFixed(4),
      lat: +lat.toFixed(4),
      rank: p.scalerank,
      name: p.sr_subunit || null,
    });
    mapped++;
  }

  // Sort + cap each country.
  for (const [iso, list] of grouped) {
    list.sort((a, b) => a.rank - b.rank);
    if (list.length > MAX_POINTS_PER_COUNTRY) {
      grouped.set(iso, list.slice(0, MAX_POINTS_PER_COUNTRY));
    }
  }

  // Emit. Sorted alphabetically by ISO for diff stability.
  const isos = [...grouped.keys()].sort();
  const lines = [];
  lines.push('// Auto-generated by map/scripts/gen-flag-positions.js');
  lines.push('// Source: Natural Earth ne_10m_admin_0_label_points (public domain).');
  lines.push('// Hand-placed by cartographers — used as flag-stamp anchors.');
  lines.push('window.WUYS_FLAG_POSITIONS = {');
  for (const iso of isos) {
    const pts = grouped.get(iso).map(p => {
      const nm = p.name ? JSON.stringify(p.name) : 'null';
      return `{lon:${p.lon},lat:${p.lat},rank:${p.rank},name:${nm}}`;
    });
    lines.push(`  "${iso}":[${pts.join(',')}],`);
  }
  lines.push('};');
  fs.writeFileSync(OUTPUT, lines.join('\n') + '\n');

  console.log('mapped:', mapped, 'skipped(rank>'+MAX_RANK+'):', skippedRank, 'skipped(unknown iso):', skippedIso);
  console.log('countries with positions:', isos.length);
  console.log('wrote:', OUTPUT, '→', fs.statSync(OUTPUT).size, 'bytes');
}

main();
