/* ============================================================
   FLEET IMPORT PARSER
   Tolerant parser for pasted "Text Export" output from common
   Armada fleet builders (Kingston / Warlords / Flagship style).
   Produces the normalized Fleet schema from the spec (§4.3).
   NOTE: yields names/points/upgrades/squadrons only — no combat
   stats (those need a separate dataset, §4.4). Imported ships are
   flagged statsMissing until the user fills them in.
   ============================================================ */

const FACTION_ALIASES = [
  [/galactic\s+empire|imperial|empire/i, "empire"],
  [/rebel\s+alliance|rebels?/i, "rebel"],
  [/galactic\s+republic|republic|gar\b/i, "republic"],
  [/separatist|cis\b|confederacy/i, "separatist"],
];
function detectFaction(text) {
  const m = text.match(/faction[:\-\s]+([^\n]+)/i);
  const probe = m ? m[1] : text.slice(0, 400);
  for (const [re, id] of FACTION_ALIASES) if (re.test(probe)) return id;
  for (const [re, id] of FACTION_ALIASES) if (re.test(text)) return id;
  return "empire";
}

function estimateSize(points) {
  if (points < 50) return "small";
  if (points < 100) return "medium";
  if (points < 145) return "large";
  return "huge";
}

const PTS_END = /\((\d+)\s*(?:pts?|points?)?\)\s*$/i; // "(85)" or "(85 pts)"
const numAt = (s) => { const m = s.match(PTS_END); return m ? parseInt(m[1], 10) : null; };
const stripPts = (s) => s.replace(PTS_END, "").trim();
const isBullet = (s) => /^\s*([-•*▪◦·]|•)\s+/.test(s) || /^\s{2,}\S/.test(s);
const debullet = (s) => s.replace(/^\s*([-•*▪◦·]|•)\s+/, "").trim();

function parseFleet(raw) {
  const text = (raw || "").replace(/\r/g, "");
  if (!text.trim()) return { ok: false, error: "Leeg — plak eerst een Text Export.", raw };

  const lines = text.split("\n");
  const fleet = {
    name: null, faction: detectFaction(text), commander: null, totalPoints: null,
    ships: [], squadrons: [],
    objectives: { assault: null, defense: null, navigation: null },
  };

  let cur = null;          // current ship being built
  let inSquadrons = false;
  let sawAnyShip = false;

  const pushShip = () => { if (cur) { fleet.ships.push(cur); cur = null; } };

  for (let rawLine of lines) {
    const line = rawLine.replace(/\t/g, "  ");
    const t = line.trim();
    if (!t) { continue; }

    // ---- meta lines ----
    let m;
    if ((m = t.match(/^name[:\-\s]+(.+)$/i)))           { fleet.name = m[1].trim(); continue; }
    if ((m = t.match(/^faction[:\-\s]+(.+)$/i)))        { continue; }
    if ((m = t.match(/^commander[:\-\s]+(.+)$/i)))      { pushShip(); fleet.commander = m[1].trim(); continue; }
    if ((m = t.match(/^assault[\s:\-]*objective?[:\-\s]+(.+)$/i)))    { pushShip(); fleet.objectives.assault = m[1].trim(); continue; }
    if ((m = t.match(/^defen[cs]e[\s:\-]*objective?[:\-\s]+(.+)$/i))) { pushShip(); fleet.objectives.defense = m[1].trim(); continue; }
    if ((m = t.match(/^navigation[\s:\-]*objective?[:\-\s]+(.+)$/i))) { pushShip(); fleet.objectives.navigation = m[1].trim(); continue; }
    if ((m = t.match(/^(?:total|fleet)\s*(?:points|cost)[:\-\s]+(\d+)/i))) { pushShip(); fleet.totalPoints = parseInt(m[1], 10); continue; }

    if (/^squadrons?[:\s]*$/i.test(t)) { pushShip(); inSquadrons = true; continue; }
    if (/^(ships?|fleet)[:\s]*$/i.test(t)) { pushShip(); inSquadrons = false; continue; }

    // ship subtotal line "= 97 Points" / "97 total"
    if (/^[=≡]\s*\d+/.test(t) || /^\d+\s*(?:total\s*)?points?$/i.test(t)) { continue; }

    const pts = numAt(t);

    // ---- squadrons ----
    if (inSquadrons) {
      if (pts == null) continue;
      let body = stripPts(debullet(t));
      let count = 1;
      const cm = body.match(/^(\d+)\s*[x×]\s*(.+)$/i);
      if (cm) { count = parseInt(cm[1], 10); body = cm[2].trim(); }
      fleet.squadrons.push({ id: uid("sq"), name: body, points: pts, count });
      continue;
    }

    // ---- ship vs upgrade ----
    if (isBullet(rawLine) && cur) {
      // upgrade line
      const body = stripPts(debullet(t));
      if (body) cur.upgrades.push({ name: body, points: pts != null ? pts : 0 });
      continue;
    }

    if (pts != null) {
      // a new ship header
      pushShip();
      sawAnyShip = true;
      cur = { name: stripPts(t), points: pts, upgrades: [] };
      continue;
    }
    // a non-pointed, non-bullet line that isn't meta: treat as upgrade if inside a ship, else ignore
    if (cur && isBullet(rawLine)) {
      cur.upgrades.push({ name: debullet(t), points: 0 });
    }
  }
  pushShip();

  if (!sawAnyShip && fleet.squadrons.length === 0) {
    return { ok: false, error: "Geen schepen of squadrons herkend. Controleer of dit een Text Export is.", raw };
  }
  if (fleet.totalPoints == null) {
    fleet.totalPoints =
      fleet.ships.reduce((s, sh) => s + sh.points + sh.upgrades.reduce((u, x) => u + x.points, 0), 0) +
      fleet.squadrons.reduce((s, q) => s + q.points * q.count, 0);
  }
  return { ok: true, fleet, raw };
}

// Convert parsed fleet → placed ship tokens (stats missing, editable later)
function fleetToShips(fleet, side) {
  // side: -1 places left, +1 places right
  const ships = [];
  const n = fleet.ships.length;
  fleet.ships.forEach((ps, i) => {
    const size = estimateSize(ps.points);
    const col = i % 2;
    const row = Math.floor(i / 2);
    const baseX = side < 0 ? -360 : 220;
    const x = baseX + col * 150 * (side < 0 ? -1 : 1);
    const y = -120 + row * 130;
    ships.push(makeShip({
      name: ps.name, faction: fleet.faction, baseSize: size,
      points: ps.points, upgrades: ps.upgrades,
      facing: side < 0 ? 90 : 270,
      x, y,
      statsMissing: true,
    }));
  });
  return ships;
}

const EXAMPLE_EXPORT = `Name: Raddus Vanguard
Faction: Rebel Alliance
Commander: Admiral Raddus

Assault Objective: Most Wanted
Defense Objective: Contested Outpost
Navigation Objective: Solar Corona

MC75 Command Cruiser (100)
- Strategic Adviser (4)
- Spinal Armament (9)
- Electronic Countermeasures (7)
= 120 Points

Nebulon-B Escort Frigate (57)
- Salvation (7)
- Engine Techs (8)
= 72 Points

CR90 Corvette A (44)
- Turbolaser Reroute Circuits (7)
= 51 Points

Squadrons:
- 2 x X-wing Squadron (26)
- 1 x Y-wing Squadron (10)
= 36 Points

Total Points: 279`;

Object.assign(window, { parseFleet, fleetToShips, estimateSize, EXAMPLE_EXPORT });
