// ─────────────────────────────────────────────────────────────────────
// RECEIPT DATA — the mock invoice the prototype extracts.
//
// Deliberately the hardest real-world case: an INTERNATIONAL engine
// builder's invoice, in EUR, whose line items belong to two different
// cars owned by two different people — plus shared shop overhead.
//
// Nothing here is a "total the user typed". Every roll-up is computed
// from the extracted line items, so the workflow can honestly promise:
// you never key a total by hand.
// ─────────────────────────────────────────────────────────────────────

const RECEIPT = {
  // What channel the document arrived through, and who put it in the system.
  intake: {
    channel: 'Email-in',
    from: 'buchhaltung@rennsport-technik.de',
    addedBy: { name: 'Rennsport Technik', initials: 'RT', role: 'Vendor (forwarded)' },
    reviewer: { name: 'You', initials: 'YOU', role: 'Principal' },
    file: 'RT-2026-0488.pdf',
    size: '1.4 MB',
    received: 'Today · 09:12',
  },

  // Header fields the OCR / CV pass pulls off the document.
  vendor: {
    name: 'Rennsport Technik GmbH',
    kind: 'Engine builder',
    city: 'Stuttgart, DE',
    vatId: 'DE 811 234 567',
    invoiceNo: 'RT-2026-0488',
    date: '14 May 2026',
    terms: 'Net 30 · wire transfer',
  },

  // Currency: original is EUR, home ledger is USD. The FX rate + date are
  // captured so the converted figure is always reproducible.
  currency: {
    code: 'EUR', symbol: '€',
    home: 'USD', homeSymbol: '$',
    rate: 1.08, rateDate: '14 May 2026', rateSource: 'ECB reference',
  },

  vatRate: 0.19, // German VAT, read off the invoice

  // Line items — net (pre-VAT) amounts in EUR. `suggest` is the AI's
  // best-guess allocation target; `conf` drives how it's presented.
  lines: [
    { id: 'l1', desc: 'Engine rebuild — pistons, rings, main & rod bearing set',
      qty: 1, unit: 'set', net: 8940,
      suggest: 'old-yeller', conf: 'High',
      why: '“Engine rebuild” matched to the active 2.7 MFI build',
      learned: '7 prior Rennsport Technik invoices booked to this build' },
    { id: 'l2', desc: 'Crankshaft regrind & rebalance',
      qty: 1, unit: 'job', net: 2180,
      suggest: 'old-yeller', conf: 'High',
      why: 'Same engine teardown as the line above',
      learned: 'Always paired with the 2.7 MFI engine work' },
    { id: 'l3', desc: 'Cylinder head overhaul — seats, guides, 3-angle valve job',
      qty: 1, unit: 'job', net: 5640,
      suggest: 'mercedes-300sl', conf: 'High',
      why: '“Cylinder head” · 300 SL head logged out for machining',
      learned: '300 SL head checked out to this vendor on Apr 9' },
    { id: 'l4', desc: 'Mechanical injection pump calibration (bench)',
      qty: 1, unit: 'job', net: 3250,
      suggest: 'mercedes-300sl', conf: 'Medium',
      why: 'M198 mechanical injection · 300 SL in restoration',
      learned: null },
    { id: 'l5', desc: 'Shop supplies & consumables',
      qty: 1, unit: 'lot', net: 420,
      suggest: 'overhead', conf: 'High',
      why: 'Not vehicle-specific · books to collection overhead',
      learned: 'Consumables from this vendor always book to overhead' },
    { id: 'l6', desc: 'Export crating & sea freight (DE → US)',
      qty: 1, unit: 'job', net: 1180,
      suggest: 'overhead', conf: 'Medium',
      why: 'Covers the whole shipment · shared overhead',
      learned: null },
  ],

  // Who owns what, and who fronted the money. Drives the reimbursement
  // roll-up at the end of the flow.
  members: [
    { id: 'you', name: 'You',         initials: 'YOU', role: 'Principal' },
    { id: 'mc',  name: 'M. Castell',  initials: 'MC',  role: 'Co-owner' },
  ],
  vehicleOwner: { 'old-yeller': 'you', 'mercedes-300sl': 'mc', 'ferrari-275': 'you' },
  paidBy: { id: 'collection', name: 'Collection account', initials: 'CA', kind: 'Shared wire' },
};

// The "shared overhead" allocation target — a first-class destination that
// is NOT a vehicle. Costs filed here are collection operating expenses.
const OVERHEAD_TARGET = {
  id: 'overhead',
  isOverhead: true,
  title: 'Collection Overhead',
  sub: 'Shared operating expense',
};

// The "no assignment" target — a TEMPORARY review state, not a final
// destination. Used when the correct vehicle can't be determined yet.
// Records stay active and searchable but are flagged for an owner /
// administrator / collection manager to resolve later.
const REVIEW_TARGET = {
  id: 'review',
  isReview: true,
  title: 'No assignment',
  sub: 'Pending review',
};

// ── money helpers ──────────────────────────────────────────────────────
const eur = (n) => RECEIPT.currency.symbol + n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const usd = (n) => RECEIPT.currency.homeSymbol + n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const toHome = (n) => n * RECEIPT.currency.rate;
const vatOf = (net) => net * RECEIPT.vatRate;
const grossOf = (net) => net * (1 + RECEIPT.vatRate);

// Document-level computed figures (never hand-keyed).
function receiptTotals() {
  const sub = RECEIPT.lines.reduce((s, l) => s + l.net, 0);
  const vat = vatOf(sub);
  const total = sub + vat;
  return { sub, vat, total, home: toHome(total) };
}

// Given a map of lineId -> allocation, roll the invoice up per target.
// allocation = { mode:'vehicle'|'overhead'|'split'|'none', vehicleId?, splits?:[{id,pct}] }
// Returns { byTarget: {targetId: {netE, vatE, grossE, homeUsd, lineIds[]}}, unallocated:[ids] }
function rollUp(targets) {
  const byTarget = {};
  const unallocated = [];
  const bump = (id, net) => {
    if (!byTarget[id]) byTarget[id] = { netE: 0, vatE: 0, grossE: 0, homeUsd: 0, lineIds: [] };
    byTarget[id].netE += net;
  };
  RECEIPT.lines.forEach(l => {
    const a = targets[l.id];
    if (!a) { unallocated.push(l.id); return; }
    if (a.mode === 'split' && a.splits && a.splits.length) {
      const totalPct = a.splits.reduce((s, p) => s + (p.pct || 0), 0) || 1;
      a.splits.forEach(p => {
        const share = l.net * ((p.pct || 0) / totalPct);
        bump(p.id, share);
        byTarget[p.id].lineIds.push(l.id);
      });
    } else {
      const id = a.mode === 'overhead' ? 'overhead' : a.mode === 'none' ? 'review' : a.vehicleId;
      if (!id) { unallocated.push(l.id); return; }
      bump(id, l.net);
      byTarget[id].lineIds.push(l.id);
    }
  });
  // finalize VAT + home conversion proportionally
  Object.values(byTarget).forEach(t => {
    t.vatE = vatOf(t.netE);
    t.grossE = t.netE + t.vatE;
    t.homeUsd = toHome(t.grossE);
  });
  return { byTarget, unallocated };
}

Object.assign(window, {
  RECEIPT, OVERHEAD_TARGET, REVIEW_TARGET,
  eur, usd, toHome, vatOf, grossOf, receiptTotals, rollUp,
});
