#!/usr/bin/env node
/*
 * Import horde entries from the staged 40k RPG Tools index as compact
 * reviewable bestiary rows. These are derived entries, not PDF-parsed
 * statblocks, so they are flagged as hordes and kept intentionally small.
 */
const fs = require('fs');
const path = require('path');
const { bestiaryHelpers, initializationPromise } = require('../database/mariadb');

const ROOT = path.join(__dirname, '..');
const INDEX_PATH = path.join(ROOT, 'database', 'remote-extract', '40krpgtools-bestiary-index.json');
const PUBLIC_PATH = path.join(ROOT, 'public', 'deathwatch-bestiary-extracted.json');
const DB_PATH = path.join(ROOT, 'database', 'deathwatch-bestiary-extracted.json');

const HORDE_SPECS = {
  'Mutant Horde': { magnitude: 20, profile: { ws: 30, bs: 20, s: 30, t: 30, ag: 30, int: 20, per: 30, wp: 30, fel: 20 }, damage: '1d10+3 I', pen: 0, armour: 3, tb: 3 },
  'PDF Guardsman Horde': { magnitude: 20, profile: { ws: 30, bs: 35, s: 30, t: 30, ag: 30, int: 30, per: 30, wp: 30, fel: 25 }, damage: '1d10+3 I', pen: 0, armour: 4, tb: 3 },
  'Rebel Horde': { magnitude: 20, profile: { ws: 30, bs: 30, s: 30, t: 30, ag: 30, int: 25, per: 30, wp: 30, fel: 25 }, damage: '1d10+3 I', pen: 0, armour: 4, tb: 3 },
  'Kroot Carnivore Horde': { magnitude: 15, profile: { ws: 40, bs: 20, s: 35, t: 30, ag: 40, int: 20, per: 35, wp: 30, fel: 10 }, damage: '1d10+4 R', pen: 0, armour: 3, tb: 3 },
  'Regressed Kroot Carnivore Horde': { magnitude: 15, profile: { ws: 40, bs: 20, s: 35, t: 30, ag: 40, int: 20, per: 35, wp: 30, fel: 10 }, damage: '1d10+4 R', pen: 0, armour: 3, tb: 3 },
  'Hromagaunt Horde': { magnitude: 20, profile: { ws: 45, bs: 20, s: 35, t: 30, ag: 55, int: 10, per: 40, wp: 30, fel: 5 }, damage: '1d10+5 R', pen: 0, armour: 3, tb: 3 },
  'Termagaunt Horde': { magnitude: 20, profile: { ws: 30, bs: 30, s: 30, t: 30, ag: 30, int: 10, per: 30, wp: 30, fel: 5 }, damage: '1d10+4 R', pen: 0, armour: 3, tb: 3 },
  'Gargoyle Horde': { magnitude: 20, profile: { ws: 30, bs: 33, s: 32, t: 30, ag: 40, int: 10, per: 40, wp: 30, fel: 0 }, damage: '1d10+5 R', pen: 3, armour: 3, tb: 3 },
};

function loadJson(file) {
  const raw = JSON.parse(fs.readFileSync(file, 'utf8'));
  const arr = Array.isArray(raw) ? raw : (raw.results || raw.entries || raw.items || []);
  if (!Array.isArray(arr)) throw new Error(`Unsupported bestiary JSON shape: ${file}`);
  return { raw, arr };
}

function norm(value) {
  return String(value || '').toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim();
}

function appendHordeEntries(arr, indexRows) {
  const existing = new Set(arr.map(entry => norm(entry.bestiaryName || entry.name)).filter(Boolean));
  const added = [];
  for (const row of indexRows.filter(r => /horde/i.test(String(r.name || '')))) {
    const key = norm(row.name);
    if (existing.has(key)) continue;
    const spec = HORDE_SPECS[row.name] || {
      magnitude: 20,
      profile: { ws: 30, bs: 25, s: 30, t: 30, ag: 30, int: 20, per: 30, wp: 30, fel: 20 },
      damage: '1d10+3 I',
      pen: 0,
      armour: 3,
      tb: 3,
    };

    const stats = {
      horde: true,
      magnitude: spec.magnitude,
      profile: spec.profile,
      wounds: spec.magnitude,
      toughnessBonus: spec.tb,
      armour: spec.armour,
      statSource: 'index-horde',
      needsReview: true,
      sourceIndex: '40krpgtools-horde-index',
      threatTier: 'Horde',
      weapons: `Massed attacks (${spec.damage}; Pen ${spec.pen})`,
    };

    arr.push({
      bestiaryName: row.name,
      type: row.type,
      affiliation: row.affiliation,
      book: row.book,
      page: row.page,
      sourceUrl: row.sourceUrl,
      wounds: spec.magnitude,
      stats,
      horde: true,
      magnitude: spec.magnitude,
    });
    existing.add(key);
    added.push(row.name);
  }
  return added;
}

async function main() {
  const index = JSON.parse(fs.readFileSync(INDEX_PATH, 'utf8'));
  const hordeRows = (index.entries || []).filter(row => /horde/i.test(String(row.name || '')));
  const { raw, arr } = loadJson(PUBLIC_PATH);
  const added = appendHordeEntries(arr, hordeRows);

  let payload;
  if (Array.isArray(raw)) {
    payload = arr;
  } else {
    raw.results = arr;
    raw.count = arr.length;
    raw.generatedAt = new Date().toISOString();
    payload = raw;
  }
  const serialized = JSON.stringify(payload, null, 2);
  for (const file of [PUBLIC_PATH, DB_PATH]) {
    if (fs.existsSync(file)) fs.writeFileSync(file + '.pre-horde.' + Date.now() + '.json', fs.readFileSync(file));
    fs.writeFileSync(file, serialized);
  }

  await initializationPromise;
  await bestiaryHelpers.replaceAll(arr);

  console.log(`Imported ${added.length} horde entries into bestiary`);
  added.forEach(name => console.log(`  + ${name}`));
}

main()
  .then(() => process.exit(0))
  .catch(error => {
    console.error(error);
    process.exit(1);
  });
