// Invoice storage — index + per-invoice keys, mirrors the shot-list pattern.
//
// Keys:
//   pp-invoice-index-v1          → [{id, number, clientName, date, total,
//                                    currency, mode, paid, favourite, archived,
//                                    createdAt, updatedAt, deletedAt?}]
//   pp-invoice.<id>              → per-invoice state (same shape as
//                                    defaultInvoice() returns)
//   pp-invoice-v1                → legacy single-invoice key, migrated on
//                                    first run.
//
// All helpers are exposed on `window` so other scripts can call them.

const INVOICE_LEGACY_KEY    = 'pp-invoice-v1';
const INVOICE_INDEX_KEY     = 'pp-invoice-index-v1';
const INVOICE_KEY_PREFIX    = 'pp-invoice.';
const INVOICE_TRASH_TTL_MS  = 30 * 24 * 60 * 60 * 1000;   // 30 days

const invoiceKey = id => INVOICE_KEY_PREFIX + id;

function loadInvoiceIndex() {
  try {
    const raw = localStorage.getItem(INVOICE_INDEX_KEY);
    if (raw) {
      const arr = JSON.parse(raw);
      if (Array.isArray(arr)) return arr;
    }
  } catch (e) { console.error('invoice index parse failed', e); }
  return null;
}
function saveInvoiceIndex(list) {
  try { localStorage.setItem(INVOICE_INDEX_KEY, JSON.stringify(list)); }
  catch (e) { console.error('invoice index save failed', e); }
}

// Pull display fields out of full invoice data so the index row stays light.
function deriveMetaFromData(data) {
  const totals = calcTotals(data);
  const clientName = (data.billTo || '').split('\n')[0].trim();
  return {
    number: data.number || '',
    clientName,
    date: data.date || todayISO(),
    total: totals.total,
    currency: data.currency,
    mode: data.mode || 'invoice',
    paid: !!data.paid,
  };
}

// First-run migration: turn the old single-invoice key into the first entry
// of the new index. Safe to call repeatedly — no-op once the index exists.
function migrateLegacyInvoiceIfNeeded() {
  if (loadInvoiceIndex() !== null) return;
  const raw = localStorage.getItem(INVOICE_LEGACY_KEY);
  if (!raw) { saveInvoiceIndex([]); return; }
  try {
    const parsed = JSON.parse(raw);
    const data = { ...defaultInvoice(), ...parsed };
    const id = crypto.randomUUID();
    const now = Date.now();
    localStorage.setItem(invoiceKey(id), JSON.stringify(data));
    saveInvoiceIndex([{
      id,
      ...deriveMetaFromData(data),
      favourite: false,
      archived: false,
      createdAt: now,
      updatedAt: now,
    }]);
    // Leave the legacy key in place as a safety net.
  } catch (e) {
    console.error('legacy invoice migration failed', e);
    saveInvoiceIndex([]);
  }
}

// Highest numeric portion across all (including trashed) invoice numbers + 1.
// Falls back to "001" when there are none. Always 3 digits, zero-padded
// (rolls over to 4+ digits naturally once you cross 999).
function nextInvoiceNumber() {
  const list = loadInvoiceIndex() || [];
  let max = 0;
  for (const m of list) {
    const n = parseInt(String(m.number || '').replace(/\D/g, ''), 10);
    if (Number.isFinite(n) && n > max) max = n;
  }
  return String(max + 1).padStart(3, '0');
}

function createInvoice(opts) {
  opts = opts || {};
  const id = crypto.randomUUID();
  const now = Date.now();
  const number = opts.number || nextInvoiceNumber();
  // Build the initial per-invoice state from defaults + any seed.
  const data = { ...defaultInvoice(), number, ...(opts.seed || {}) };
  localStorage.setItem(invoiceKey(id), JSON.stringify(data));
  const list = loadInvoiceIndex() || [];
  list.push({
    id,
    ...deriveMetaFromData(data),
    favourite: false,
    archived: false,
    createdAt: now,
    updatedAt: now,
  });
  saveInvoiceIndex(list);
  return id;
}

// Deep-copy an existing invoice, assign a fresh id + next number, save it.
// Returns the new id (or null if the source is missing).
function duplicateInvoiceStorage(id) {
  const raw = localStorage.getItem(invoiceKey(id));
  if (!raw) return null;
  try {
    const data = JSON.parse(raw);
    const newId = crypto.randomUUID();
    const number = nextInvoiceNumber();
    const newData = { ...data, number };
    localStorage.setItem(invoiceKey(newId), JSON.stringify(newData));
    const list = loadInvoiceIndex() || [];
    const now = Date.now();
    list.push({
      id: newId,
      ...deriveMetaFromData(newData),
      favourite: false,
      archived: false,
      createdAt: now,
      updatedAt: now,
    });
    saveInvoiceIndex(list);
    return newId;
  } catch (e) {
    console.error('duplicate invoice failed', e);
    return null;
  }
}

function updateInvoiceMeta(id, patch) {
  const list = loadInvoiceIndex() || [];
  const i = list.findIndex(m => m.id === id);
  if (i < 0) return;
  list[i] = { ...list[i], ...patch, updatedAt: Date.now() };
  saveInvoiceIndex(list);
}

function trashInvoice(id) {
  const list = loadInvoiceIndex() || [];
  const m = list.find(x => x.id === id);
  if (!m) return;
  m.deletedAt = Date.now();
  m.favourite = false;
  m.archived  = false;
  saveInvoiceIndex(list);
}
function restoreInvoice(id) {
  const list = loadInvoiceIndex() || [];
  const m = list.find(x => x.id === id);
  if (!m) return;
  delete m.deletedAt;
  m.updatedAt = Date.now();
  saveInvoiceIndex(list);
}
function deleteInvoiceStorage(id) {
  const next = (loadInvoiceIndex() || []).filter(m => m.id !== id);
  saveInvoiceIndex(next);
  localStorage.removeItem(invoiceKey(id));
}
function purgeExpiredInvoices() {
  const list = loadInvoiceIndex() || [];
  const now = Date.now();
  const survivors = [];
  for (const m of list) {
    if (m.deletedAt && now - m.deletedAt >= INVOICE_TRASH_TTL_MS) {
      localStorage.removeItem(invoiceKey(m.id));
    } else {
      survivors.push(m);
    }
  }
  if (survivors.length !== list.length) saveInvoiceIndex(survivors);
}

Object.assign(window, {
  INVOICE_LEGACY_KEY, INVOICE_INDEX_KEY, INVOICE_KEY_PREFIX, INVOICE_TRASH_TTL_MS,
  invoiceKey,
  loadInvoiceIndex, saveInvoiceIndex,
  migrateLegacyInvoiceIfNeeded, nextInvoiceNumber,
  createInvoice, duplicateInvoiceStorage, updateInvoiceMeta,
  trashInvoice, restoreInvoice, deleteInvoiceStorage, purgeExpiredInvoices,
  deriveMetaFromData,
});
