#!/usr/bin/env node
/**
 * build-data.js
 * Converts the Home Office "Register of licensed sponsors: workers" CSV
 * into the compact JSON the Sponzza extension bundles and matches against.
 *
 * Usage:
 *   node build-data.js <path-to-csv>
 *   node build-data.js                 (defaults to data/sponsors.sample.csv)
 *
 * Output: data/sponsors.json
 *
 * It auto-detects the organisation-name column, so it works whether the
 * header is "Organisation Name", "Organisation name", "Employer Name", etc.
 */

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

// ---- Normalisation (MUST stay in sync with src/matcher.mjs) ----------------
const STRIP_WORDS = new Set([
  'ltd', 'limited', 'llp', 'llc', 'plc', 'inc', 'incorporated', 'corp',
  'corporation', 'co', 'company', 'group', 'holdings', 'holding', 'uk',
  'gb', 'gbr', 'the', 'and', 'intl', 'international', 'services', 'service',
  'solutions', 'global', 'europe', 'emea', 'unlimited',
]);

function normalize(name) {
  if (!name) return '';
  let s = String(name)
    .toLowerCase()
    .normalize('NFKD').replace(/[\u0300-\u036f]/g, '') // strip accents
    .replace(/&/g, ' and ')
    .replace(/[^a-z0-9\s]/g, ' ')                       // drop punctuation
    .replace(/\s+/g, ' ')
    .trim();

  const kept = s.split(' ').filter((w) => w && !STRIP_WORDS.has(w));
  // If stripping removed everything (e.g. name was just "The Group"), fall back.
  return (kept.length ? kept.join(' ') : s.replace(/\s+/g, ' ').trim());
}

// ---- Minimal RFC-4180-ish CSV parser (handles quoted fields & commas) ------
function parseCSV(text) {
  const rows = [];
  let row = [], field = '', inQuotes = false;
  for (let i = 0; i < text.length; i++) {
    const c = text[i];
    if (inQuotes) {
      if (c === '"') {
        if (text[i + 1] === '"') { field += '"'; i++; }
        else inQuotes = false;
      } else field += c;
    } else {
      if (c === '"') inQuotes = true;
      else if (c === ',') { row.push(field); field = ''; }
      else if (c === '\n') { row.push(field); rows.push(row); row = []; field = ''; }
      else if (c === '\r') { /* ignore */ }
      else field += c;
    }
  }
  if (field.length || row.length) { row.push(field); rows.push(row); }
  return rows;
}

function detectNameColumn(header) {
  const candidates = [
    'organisation name', 'organization name', 'organisation', 'organization',
    'employer name', 'company name', 'name', 'sponsor name',
  ];
  const lower = header.map((h) => h.trim().toLowerCase());
  for (const cand of candidates) {
    const idx = lower.indexOf(cand);
    if (idx !== -1) return idx;
  }
  // Fallback: first column.
  return 0;
}

// ---- Main ------------------------------------------------------------------
const inputPath = process.argv[2] || path.join(__dirname, 'data', 'sponsors.sample.csv');
const outputPath = path.join(__dirname, 'data', 'sponsors.json');

if (!fs.existsSync(inputPath)) {
  console.error(`✗ CSV not found: ${inputPath}`);
  process.exit(1);
}

console.log(`Reading: ${inputPath}`);
const raw = fs.readFileSync(inputPath, 'utf8');
const rows = parseCSV(raw).filter((r) => r.length && r.some((c) => c && c.trim()));

if (rows.length < 2) {
  console.error('✗ CSV appears empty or has no data rows.');
  process.exit(1);
}

const header = rows[0];
const nameIdx = detectNameColumn(header);
console.log(`Detected name column: "${header[nameIdx]}" (index ${nameIdx})`);

const byKey = {};      // normalizedKey -> display name (first occurrence wins)

let kept = 0;
for (let i = 1; i < rows.length; i++) {
  const display = (rows[i][nameIdx] || '').trim();
  if (!display) continue;
  const key = normalize(display);
  if (!key) continue;
  if (!(key in byKey)) byKey[key] = display;
  kept++;
}

const out = {
  meta: {
    source: path.basename(inputPath),
    generatedAt: new Date().toISOString(),
    rawRows: rows.length - 1,
    uniqueKeys: Object.keys(byKey).length,
    isSample: path.basename(inputPath).includes('sample'),
  },
  byKey,
};

fs.writeFileSync(outputPath, JSON.stringify(out));
const sizeMB = (fs.statSync(outputPath).size / 1024 / 1024).toFixed(2);
console.log(`✓ Wrote ${outputPath}`);
console.log(`  Rows in:        ${out.meta.rawRows.toLocaleString()}`);
console.log(`  Unique keys:    ${out.meta.uniqueKeys.toLocaleString()}`);
console.log(`  File size:      ${sizeMB} MB`);
if (out.meta.isSample) console.log('  ⚠ Built from SAMPLE data — swap in the real CSV before publishing.');
