/* ============================================================
   HOCHZEITSPLANER — PDF Parser & Import View
   Parsed die Numbers-PDF und extrahiert:
     - Budget-Kategorien (Hochzeit + Honeymoon)
     - Sparpläne (Hochzeit, Honeymoon, Household Credit)
   ============================================================ */

const PARSER = (() => {
  const parseAmount = (s) => parseFloat(String(s).replace(/\./g, "").replace(",", "."));

  const KNOWN_WEDDING_CATS = [
    "Location + Food",
    "Family traveling costs",
    "Photo- & Videographer",
    "Bride dress",
    "Rings",
    "Groom suit + shoes",
    "Deco",
    "Cake",
    "DJ Case",
    "Bride makeup",
    "Standesamt",
    "Sonstige",
  ];
  const KNOWN_HONEYMOON_CATS = [
    "Flights",
    "Accommodation",
    "Free Money",
    "Car",
    "VISAs",
  ];

  // Find named sections in the full text.
  // IMPORTANT: section TITLES appear at the BOTTOM of each PDF page (footer),
  // not at the top. So the content for a section is the text BEFORE its marker
  // (back to the previous marker), not after.
  function splitSections(text) {
    const markers = [
      { key: "weddingBudget",    re: /Wedding Budget\s*22\.08\.2026/i },
      { key: "honeymoonBudget",  re: /Honeymoon Budget/i },
      { key: "weddingSavings",   re: /Saving plan for Wedding/i },
      { key: "honeymoonSavings", re: /saving plan for Honeymoon/i },
      { key: "householdCredit",  re: /Household Credit/i },
    ];
    const positions = markers
      .map((m) => {
        const match = text.match(m.re);
        return { ...m, index: match ? match.index : -1, length: match ? match[0].length : 0 };
      })
      .filter((p) => p.index >= 0)
      .sort((a, b) => a.index - b.index);

    const sections = {};
    let prevEnd = 0;
    for (let i = 0; i < positions.length; i++) {
      // Text from previous marker end up to this marker's start
      // = content that belongs to THIS section (because its title is at page footer)
      sections[positions[i].key] = text.slice(prevEnd, positions[i].index);
      prevEnd = positions[i].index + positions[i].length;
    }
    return sections;
  }

  // For each known category name, extract budget + paid from its section
  function parseCategoryList(sectionText, names) {
    const out = [];
    for (const name of names) {
      const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
      // Allow amounts with OR without thousands separator (PDF has "2000,00" in places)
      const amount = `(\\d[\\d.]*,\\d{2})`;
      const re = new RegExp(`${escaped}\\s*€?\\s+${amount}\\s*€?\\s+${amount}`);
      const m = sectionText.match(re);
      if (m) {
        out.push({ name, budget: parseAmount(m[1]), paid: parseAmount(m[2]) });
      } else {
        const re2 = new RegExp(`${escaped}\\s*€?\\s+${amount}`);
        const m2 = sectionText.match(re2);
        if (m2) out.push({ name, budget: parseAmount(m2[1]), paid: 0 });
        else out.push({ name, budget: 0, paid: 0 });
      }
    }
    return out;
  }

  // Parse savings rows. Format per line: "MM.YYYY € 400,00 € 400,00 € 800,00 € 800,00"
  // Some legacy formats also use "DD.MM.YYYY". Lines like "Total 	€ ..." are skipped.
  function parseSavings(sectionText) {
    // Allow amounts with OR without thousands separator
    const amountRe = /(\d[\d.]*,\d{2})/g;
    const rows = [];
    const lines = sectionText.split(/\n/);
    for (const line of lines) {
      // Reset regex lastIndex for fresh match per line
      const dm = line.match(/(\d{2}\.\d{2}\.\d{4}|\d{2}\.\d{4})/);
      if (!dm) continue;
      // skip "Total" rows
      if (/total/i.test(line)) continue;
      const amounts = [...line.matchAll(amountRe)].map((m) => parseAmount(m[1]));
      if (amounts.length < 2) continue;
      const ds = dm[1];
      let isoDate;
      if (ds.length === 7) {
        const [mm, yyyy] = ds.split(".");
        isoDate = `${yyyy}-${mm}-01`;
      } else {
        const [dd, mm, yyyy] = ds.split(".");
        isoDate = `${yyyy}-${mm}-${dd.padStart(2, "0")}`;
      }
      // sheep + shepard = first two amounts (skip date if it parsed as amount)
      // But the date pattern may overlap if year has commas? No, dates use dots so they won't match amount regex
      rows.push({ date: isoDate, sheep: amounts[0], shepard: amounts[1] });
    }
    // Sort by date
    rows.sort((a, b) => a.date.localeCompare(b.date));
    return rows;
  }

  function parsePdfText(text) {
    const sections = splitSections(text);
    return {
      wedding: parseCategoryList(sections.weddingBudget || "", KNOWN_WEDDING_CATS),
      honeymoon: parseCategoryList(sections.honeymoonBudget || "", KNOWN_HONEYMOON_CATS),
      weddingSavings:   parseSavings(sections.weddingSavings   || ""),
      honeymoonSavings: parseSavings(sections.honeymoonSavings || ""),
      householdCredit:  parseSavings(sections.householdCredit  || ""),
    };
  }

  return { parsePdfText, parseAmount, KNOWN_WEDDING_CATS, KNOWN_HONEYMOON_CATS };
})();

// =============================================================
//  PDF.js loader (dynamic import — wrapped to evade Babel transform)
// =============================================================
// Babel-standalone rewrites bare `import()` to `require()`, which breaks in
// the browser. Wrap in `new Function` so Babel doesn't see the import syntax.
const _dynamicImport = new Function("url", "return import(url)");

let _pdfModule = null;
async function loadPdfLib() {
  if (_pdfModule) return _pdfModule;
  const mod = await _dynamicImport("https://cdn.jsdelivr.net/npm/pdf-parse@2.4.5/dist/pdf-parse/web/pdf-parse.es.js");
  mod.PDFParse.setWorker("https://cdn.jsdelivr.net/npm/pdf-parse@2.4.5/dist/pdf-parse/web/pdf.worker.min.mjs");
  _pdfModule = mod;
  return mod;
}

async function parsePdfFile(file) {
  const { PDFParse } = await loadPdfLib();
  const ab = await file.arrayBuffer();
  const parser = new PDFParse({ data: new Uint8Array(ab) });
  const result = await parser.getText();
  return PARSER.parsePdfText(result.text);
}

// =============================================================
//  LOCAL STORAGE LAYER
// =============================================================
const STORAGE_KEY = "wedding-planner-override-v1";

function loadOverrides() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    return raw ? JSON.parse(raw) : null;
  } catch (e) {
    return null;
  }
}

function saveOverrides(overrides) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify({
    ...overrides,
    _meta: { savedAt: new Date().toISOString() },
  }));
}

function clearOverrides() {
  localStorage.removeItem(STORAGE_KEY);
}

// Merge base data with overrides
function mergeData(base, override) {
  if (!override) return base;
  return {
    ...base,
    wedding:   override.wedding   ? { ...base.wedding,   categories: override.wedding   } : base.wedding,
    honeymoon: override.honeymoon ? { ...base.honeymoon, categories: override.honeymoon } : base.honeymoon,
    weddingSavings:   override.weddingSavings   || base.weddingSavings,
    honeymoonSavings: override.honeymoonSavings || base.honeymoonSavings,
    householdCredit:  override.householdCredit  || base.householdCredit,
  };
}

Object.assign(window, { PARSER, parsePdfFile, loadOverrides, saveOverrides, clearOverrides, mergeData });
