import Database from "better-sqlite3";
import { XMLParser } from "fast-xml-parser";

const DB_PATH = "./src/data/ServicesRange.db";

const SOURCES = [
  {
    source: "EVIO",
    url: "https://www.jambox.pl/xml/slownik-pakietypodstawoweevio.xml",
  },
  {
    source: "PLUS",
    url: "https://www.jambox.pl/xml/slownik-pakietypodstawoweplus.xml",
  },
];

function slugify(str) {
  if (!str) return null;
  return str
    .toString()
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "");
}

async function fetchXml(url) {
  const res = await fetch(url);
  if (!res.ok) {
    throw new Error(`Błąd pobierania XML z ${url}: ${res.status} ${res.statusText}`);
  }
  return await res.text();
}

function parseNodesFromXml(xmlText) {
  const parser = new XMLParser({
    ignoreAttributes: false,
    attributeNamePrefix: "@_",
  });

  const json = parser.parse(xmlText);
  const nodes = json.xml?.node ?? json.node ?? [];

  if (Array.isArray(nodes)) return nodes;
  if (!nodes) return [];
  return [nodes];
}

function ensureSchema(db) {
  db.exec(`
    CREATE TABLE IF NOT EXISTS jambox_base_packages (
      id         INTEGER PRIMARY KEY AUTOINCREMENT,
      source     TEXT NOT NULL,
      tid        INTEGER NOT NULL,
      name       TEXT NOT NULL,
      slug       TEXT,
      sort_order INTEGER,
      updated_at TEXT NOT NULL,
      UNIQUE(source, tid)
    );
  `);
}

function upsertBasePackages(db, source, nodes) {
  const now = new Date().toISOString();

  const upsert = db.prepare(`
    INSERT INTO jambox_base_packages (source, tid, name, slug, sort_order, updated_at)
    VALUES (@source, @tid, @name, @slug, @sort_order, @updated_at)
    ON CONFLICT(source, tid) DO UPDATE SET
      name       = excluded.name,
      slug       = excluded.slug,
      sort_order = excluded.sort_order,
      updated_at = excluded.updated_at;
  `);

  const tx = db.transaction((rows) => {
    rows.forEach((node, index) => {
      const name = node.name ?? node["#text"] ?? "";
      const tidRaw = node.tid ?? node.id ?? null;

      if (!tidRaw || !name) {
        console.warn(`⚠ Pomijam node bez tid/name (source=${source}):`, node);
        return;
      }

      const tid = Number(tidRaw);

      const record = {
        source,
        tid,
        name: String(name).trim(),
        slug: slugify(String(name)),
        sort_order: index + 1,
        updated_at: now,
      };

      upsert.run(record);
    });
  });

  tx(nodes);

  console.log(`✅ ${source}: zapisano/zmieniono ${nodes.length} pakietów.`);
}

async function main() {
  console.log(`Używam bazy: ${DB_PATH}`);
  const db = new Database(DB_PATH);
  ensureSchema(db);

  for (const { source, url } of SOURCES) {
    console.log(`\n=== Przetwarzam ${source} (${url}) ===`);
    try {
      const xml = await fetchXml(url);
      const nodes = parseNodesFromXml(xml);

      console.log(`📦 Znaleziono ${nodes.length} node'ów dla ${source}`);
      upsertBasePackages(db, source, nodes);
    } catch (err) {
      console.error(`❌ Błąd przy źródle ${source}:`, err);
    }
  }

  db.close();
  console.log("\n🎉 Import pakietów podstawowych zakończony.");
}

main().catch((err) => {
  console.error("❌ Krytyczny błąd:", err);
  process.exit(1);
});
