const UNCOSTED_PTS = 4.9;
const useUse = () => { const { recipes } = useMizo(); const u = {}; recipes.forEach((r) => r.lines.forEach((l) => { u[l.ing] = (u[l.ing] || 0) + l.qty * r.sold; })); return u; };

function FinFoodBev() {
  const v = useFinView(); const { L, lang, fmt, F, O, P, calc, recipes, invMap, waste } = v; const a = P.cur;
  const mk = monthsK(), m = mk[11];
  let c = 0, s = 0; recipes.forEach((r) => { const k = recipeCost(r, invMap); c += (k.total - (r.pack || 0)) * r.sold; s += r.price * r.sold; });
  const th = (c / s) * 100, gapPts = m.foodPct - th, gap = (gapPts / 100) * m.foodRev;
  const wk = waste.filter((w) => w.date >= '2026-10-22').reduce((t, w) => t + (invMap[w.ing] ? invMap[w.ing].cost * w.qty : 0), 0);
  const parts = [
    { k: 'unc', label: L('Used but not in any recipe (sauces, garnish, oil top-ups)', 'Utilisé mais absent des recettes (sauces, garnitures, huile)'), v: (UNCOSTED_PTS / 100) * m.foodRev, prov: 'e', to: ['sales', 'pos'] },
    { k: 'cnt', label: L('Count variance (shelf below expected)', 'Écart d’inventaire'), v: 706, prov: 'v', to: ['inventory', 'variance'] },
    { k: 'waste', label: L('Waste logged', 'Pertes notées'), v: 405 + wk, prov: 'v', to: ['inventory', 'waste'] },
    { k: 'comp', label: L('Comps and staff meals', 'Offerts et repas employés'), v: 435, prov: 'e', to: ['sales', 'payments'] },
  ];
  parts.push({ k: 'unx', label: L('Not explained yet', 'Pas encore expliqué'), v: Math.max(0, gap - parts.reduce((t, x) => t + x.v, 0)), prov: 'm' });
  const bevTh = F.bevItems.reduce((t, b) => t + b.cost * b.sold, 0);
  const gapD = { title: L('Actual vs. theoretical food cost', 'Coût alimentaire réel vs théorique'), value: fmt.pct(gapPts) + ' pts', prov: 'e', period: L('Oct 1–28', '1–28 oct.'), formula: L('Gap = actual food cost % − theoretical food cost %', 'Écart = % réel − % théorique'), inputs: [{ label: L('Actual food cost %', '% réel'), v: fmt.pct(m.foodPct), prov: 'e', note: L('Food cost of goods ÷ food sales', 'Coût des aliments ÷ ventes') }, { op: '−', label: L('Theoretical (what recipes say)', 'Théorique (selon les recettes)'), v: fmt.pct(th), prov: 'e', note: L('Σ recipe ingredient cost × units sold ÷ Σ menu price × units sold', 'Σ coût des ingrédients × unités ÷ Σ prix × unités') }, { tot: true, op: '=', label: L('Gap', 'Écart'), v: fmt.pct(gapPts) + ' pts' }, { label: L('In dollars this month', 'En dollars ce mois-ci'), v: fmt.money0(gap) }], rows: { head: [L('Where it goes', 'Où ça va'), '$', L('pts', 'pts')], body: parts.map((x) => [x.label, fmt.money0(x.v), fmt.pct((x.v / m.foodRev) * 100)]) }, notes: [L('Most of the gap is ingredients the kitchen uses that no recipe accounts for. Costing sauces and garnish would make the theoretical number far more useful.', 'La majeure partie de l’écart vient d’ingrédients absents des recettes. Chiffrer sauces et garnitures rendrait le théorique bien plus utile.')], to: ['menu', 'recipes'], toLabel: L('Open recipes', 'Ouvrir les recettes') };
  return (
    <div className="page">
      <FinHead sub={L('What food and drinks cost you, what your recipes say they should cost, and where the difference goes.', 'Ce que coûtent aliments et boissons, ce que les recettes prévoient, et où va la différence.')} />
      <section className="kpis">
        <Metric hero ic="bowl-food" label={L('Food cost', 'Coût alimentaire')} value={fmt.pct(a.foodPct)} delta={<Pts v={a.foodPct - P.cmp.foodPct} invert />} cmpLab={P.cmpLab} prov={P.closed ? 'v' : 'e'} onClick={() => calc(finDrill('food', v))} />
        <Metric ic="book-open-text" label={L('Theoretical food cost', 'Coût théorique')} value={fmt.pct(th)} sub={L('from recipes × sales', 'recettes × ventes')} prov="e" onClick={() => calc(gapD)} />
        <Metric ic="arrows-in-line-horizontal" label={L('Gap this month', 'Écart ce mois-ci')} value={fmt.money0(gap)} sub={fmt.pct(gapPts) + ' pts'} prov="e" onClick={() => calc(gapD)} />
        <Metric ic="wine" label={L('Beverage cost', 'Coût des boissons')} value={fmt.pct(a.bevPct)} sub={L('theoretical', 'théorique') + ' ' + fmt.pct((bevTh / F.bevRev) * 100)} prov="e" onClick={() => calc({ title: L('Beverage cost %', '% coût des boissons'), value: fmt.pct(a.bevPct), prov: 'e', formula: L('Beverage purchases (adjusted for stock) ÷ beverage sales', 'Achats de boissons ÷ ventes de boissons'), inputs: [{ label: L('Beverage purchases, Oct', 'Achats de boissons, oct.'), v: fmt.money0(F.bevPurch), prov: 'v' }, { op: '÷', label: L('Beverage sales, Oct', 'Ventes de boissons, oct.'), v: fmt.money0(F.bevRev), prov: 'v' }, { tot: true, op: '=', label: L('Beverage cost %', '% boissons'), v: fmt.pct((F.bevPurch / F.bevRev) * 100) }, { label: L('Theoretical (item costs × sold)', 'Théorique (coûts × ventes)'), v: fmt.money0(bevTh), prov: 'e' }, { label: L('Difference — staff drinks, breakage, comps', 'Différence — boissons employés, bris, offerts'), v: fmt.money0(F.bevPurch - bevTh) }] })} />
      </section>
      <section className="grid-2-1">
        <div className="panel">
          <div className="panel-head"><div><h3>{L('Food cost %, last 12 months', '% coût alimentaire, 12 mois')}</h3><p className="muted">{L('Dashed line: 30% target', 'Pointillé : cible de 30 %')}</p></div></div>
          <LineChart labels={F.months.map((x) => x.label[lang])} series={[{ name: L('Food cost', 'Coût alimentaire'), values: mk.map((x) => x.foodPct), tone: 'a' }, { name: L('Beverage cost', 'Boissons'), values: mk.map((x) => x.bevPct), tone: 'b' }]} fmtv={(x) => fmt.pct(x)} refLine={30} refLabel="30%" height={200} />
        </div>
        <div className="panel">
          <div className="panel-head"><div><h3>{L('Why actual is higher than recipes', 'Pourquoi le réel dépasse les recettes')}</h3><p className="muted">{fmt.money0(gap)} {L('this month', 'ce mois-ci')}</p></div></div>
          <div className="gapbar">{parts.map((x, i) => <span key={x.k} className={'g' + i} style={{ flex: x.v }} title={x.label}></span>)}</div>
          {parts.map((x, i) => <button key={x.k} className="ln gap-ln" onClick={() => x.to && v.go(x.to[0], { tab: x.to[1] })}><span><i className={'sq g' + i}></i>{x.label} <Prov k={x.prov} short /></span><b>{fmt.money0(x.v)}</b></button>)}
        </div>
      </section>
      <div className="panel panel-flush">
        <div className="panel-head pad"><div><h3>{L('Beverages', 'Boissons')}</h3><p className="muted">{L('Last 30 days · bought from Distribution Gastro QC and the SAQ', '30 derniers jours · achetées chez Distribution Gastro QC et à la SAQ')}</p></div></div>
        <div className="table-scroll">
          <table className="table mtable">
            <thead><tr><th>{L('Item', 'Article')}</th><th className="num">{L('Price', 'Prix')}</th><th className="num">{L('Cost', 'Coût')}</th><th className="num">{L('Cost %', '% coût')}</th><th className="num hide-sm">{L('Sold', 'Vendus')}</th><th className="num">{L('Margin / month', 'Marge / mois')}</th></tr></thead>
            <tbody>{F.bevItems.map((b) => <tr key={b.id}><td className="cell-main">{b.name[lang]}</td><td className="num tnum">{fmt.money(b.price)}</td><td className="num tnum">{fmt.money(b.cost)}</td><td className="num"><Pill tone={(b.cost / b.price) * 100 > 30 ? 'warn' : 'pos'}>{fmt.pct((b.cost / b.price) * 100)}</Pill></td><td className="num tnum hide-sm">{fmt.num(b.sold)}</td><td className="num tnum">{fmt.money0((b.price - b.cost) * b.sold)}</td></tr>)}</tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

function FinLabour() {
  const v = useFinView(); const { L, lang, fmt, F, P, calc, employees, punches, now, go } = v; const a = P.cur;
  const mk = monthsK();
  const P2 = window.MIZO_PAY, rows = P2.calc(employees, punches, now), ot = rows.reduce((s, r) => s + r.ot, 0), otCost = rows.reduce((s, r) => s + r.ot * (r.e.rate || 0) * 0.5, 0);
  const shH = (s) => (s ? (s[1] - s[0] - (s[1] - s[0] > 300 ? 30 : 0)) / 60 : 0);
  const roleC = {}; employees.forEach((e) => { const h = Object.values(e.sched).reduce((t, s) => t + shH(s), 0); const k = e.role[lang]; roleC[k] = (roleC[k] || 0) + (e.type === 'salary' ? e.salary / 2 : h * e.rate); });
  const rt = Object.values(roleC).reduce((t, x) => t + x, 0);
  const hours = (a.lab * FR.wages) / 19.6;
  return (
    <div className="page">
      <SeeAlso k="finLabour" />
      <FinHead sub={L('What your team costs, how it moves with sales, and where overtime creeps in.', 'Ce que coûte l’équipe, comment ça suit les ventes, et où s’ajoutent les heures supp.')} />
      <section className="kpis">
        <Metric hero ic="users-three" label={L('Labour', 'Main-d’œuvre')} value={fmt.pct(a.labPct)} delta={<Pts v={a.labPct - P.cmp.labPct} invert />} cmpLab={P.cmpLab} prov={P.closed ? 'v' : 'e'} onClick={() => calc(finDrill('lab', v))} />
        <Metric ic="money" label={L('Labour cost', 'Coût de main-d’œuvre')} value={fmt.money0(a.lab)} delta={<Delta v={v.md(a.lab, P.cmp.lab)} invert />} prov={P.closed ? 'v' : 'e'} onClick={() => calc(finDrill('lab', v))} />
        <Metric ic="clock" label={L('Sales per labour hour', 'Ventes par heure')} value={fmt.money0(a.rev / hours)} sub={fmt.num(Math.round(hours)) + ' h ' + L('(est.)', '(est.)')} prov="e" onClick={() => calc({ period: P.lab, title: L('Sales per labour hour', 'Ventes par heure travaillée'), value: fmt.money0(a.rev / hours), prov: 'e', formula: L('Revenue ÷ hours worked', 'Ventes ÷ heures travaillées'), inputs: [{ label: L('Revenue', 'Ventes'), v: fmt.money0(a.rev), prov: 'v' }, { op: '÷', label: L('Hours worked', 'Heures travaillées'), v: fmt.num(Math.round(hours)), prov: 'e', note: L('Wages ÷ blended rate of $19.60/h', 'Salaires ÷ taux moyen de 19,60 $/h') }], notes: [L('Exact hours come from approved timesheets once the pay period closes.', 'Les heures exactes viendront des feuilles de temps approuvées.')], to: ['team', 'sheets'] })} />
        <Metric ic="timer" label={L('Overtime this pay period', 'Heures supp. cette période')} value={fmt.num(Math.round(ot * 10) / 10) + ' h'} sub={L('premium', 'prime') + ' ' + fmt.money0(otCost)} prov="e" onClick={() => go('team', { tab: 'run' })} />
      </section>
      <section className="grid-2-1">
        <div className="panel"><div className="panel-head"><div><h3>{L('Labour %, last 12 months', '% main-d’œuvre, 12 mois')}</h3><p className="muted">{L('Dashed line: 31% budget', 'Pointillé : budget 31 %')}</p></div></div><LineChart labels={F.months.map((x) => x.label[lang])} series={[{ name: L('Labour', 'Main-d’œuvre'), values: mk.map((x) => x.labPct), tone: 'a' }]} fmtv={(x) => fmt.pct(x)} refLine={31} refLabel="31%" height={200} /></div>
        <div className="panel"><div className="panel-head"><div><h3>{L('What it’s made of', 'Composition')}</h3><p className="muted">{P.lab}</p></div></div><HBars items={[{ label: L('Wages', 'Salaires'), v: a.lab * FR.wages }, { label: L('Employer contributions', 'Charges sociales'), v: a.lab * FR.employer, sub: 'RRQ · AE · RQAP · FSS · CNESST' }, { label: L('Vacation pay', 'Vacances'), v: a.lab * FR.vacation }]} fmtv={fmt.money0} /></div>
      </section>
      <div className="panel"><div className="panel-head"><div><h3>{L('By role', 'Par poste')}</h3><p className="muted">{L('Period cost split by scheduled hours × rate (allocated estimate)', 'Coût réparti selon heures prévues × taux (estimation)')}</p></div><button className="btn btn-secondary" onClick={() => go('team', { tab: 'labour' })}>{L('Daily labour', 'Main-d’œuvre par jour')}<Icon n="arrow-right" /></button></div><HBars items={Object.entries(roleC).map(([k, x]) => ({ label: k, v: (x / rt) * a.lab, sub: fmt.pct((x / rt) * 100) })).sort((x, y) => y.v - x.v)} fmtv={fmt.money0} /></div>
    </div>
  );
}

function FinPrime() {
  const v = useFinView(); const { L, lang, fmt, F, P, calc } = v; const a = P.cur;
  const mk = monthsK(), scale = 75, tgt = 63;
  return (
    <div className="page">
      <FinHead sub={L('Cost of goods plus labour — the two costs you can change week to week. Your target is under 63%.', 'Marchandises plus main-d’œuvre — les deux coûts modifiables chaque semaine. Cible : moins de 63 %.')} />
      <section className="kpis">
        <Metric hero ic="scales" label={L('Prime cost', 'Coût principal')} value={fmt.pct(a.primePct)} delta={<Pts v={a.primePct - P.cmp.primePct} invert />} cmpLab={P.cmpLab} prov="e" onClick={() => calc(finDrill('prime', v))} />
        <Metric ic="money" label={L('Prime cost in dollars', 'Coût principal en dollars')} value={fmt.money0(a.prime)} prov="e" onClick={() => calc(finDrill('prime', v))} />
        <Metric ic="target" label={L('Above target by', 'Au-dessus de la cible de')} value={fmt.money0(Math.max(0, ((a.primePct - tgt) / 100) * a.rev))} sub={fmt.pct(Math.max(0, a.primePct - tgt)) + ' pts'} prov="e" onClick={() => calc({ ...finDrill('prime', v), title: L('Distance to the 63% target', 'Écart avec la cible de 63 %'), value: fmt.money0(Math.max(0, ((a.primePct - tgt) / 100) * a.rev)), formula: L('(prime cost % − 63%) × revenue', '(% coût principal − 63 %) × ventes') })} />
        <Metric ic="chart-pie-slice" label={L('Cost of goods share', 'Part des marchandises')} value={fmt.pct(a.cogsPct)} sub={L('labour', 'main-d’œuvre') + ' ' + fmt.pct(a.labPct)} prov="e" onClick={() => calc(finDrill('gross', v))} />
      </section>
      <div className="panel">
        <div className="panel-head"><div><h3>{L('Prime cost by month', 'Coût principal par mois')}</h3><p className="muted">{L('Cost of goods (accent) + labour (grey) · dashed line is the 63% target', 'Marchandises (accent) + main-d’œuvre (gris) · pointillé : cible de 63 %')}</p></div></div>
        <div className="stack">
          <div className="stack-target" style={{ bottom: `calc(1.9rem + ${(200 * tgt) / scale}px)` }}><span>63%</span></div>
          {mk.map((x, i) => (
            <button key={i} className={'stack-col' + (i === 11 ? ' last' : '')} onClick={() => calc({ ...finDrill('prime', { ...v, P: { ...P, cur: x, cmp: monthsK()[Math.max(0, i - 1)], lab: F.months[i].label[lang], cmpLab: L('previous month', 'mois précédent') } }) })} title={F.months[i].label[lang]}>
              <span className="stack-val tnum">{fmt.pct(x.primePct)}</span>
              <span className="stack-bar"><span className="stack-l" style={{ height: (x.labPct / scale) * 100 + '%' }}></span><span className="stack-f" style={{ height: (x.cogsPct / scale) * 100 + '%' }}></span></span>
              <span className="bars-label">{F.months[i].label[lang]}</span>
            </button>
          ))}
        </div>
      </div>
    </div>
  );
}

function FinCosts() {
  const v = useFinView(); const { L, lang, fmt, F, D, P, calc } = v; const a = P.cur, b = P.cmp;
  const mk = monthsK(), cc = F.cogsCalc;
  const supN = (k) => (D.suppliers.find((s) => s.id === k) || {}).name || { pack: L('Emballages Carrousel (packaging)', 'Emballages Carrousel'), bev: L('Beverages — Distribution Gastro QC, SAQ', 'Boissons — Distribution Gastro QC, SAQ'), misc: L('Small purchases (Costco, Adonis)', 'Petits achats (Costco, Adonis)') }[k];
  const cogsD = { title: L('Cost of goods sold, October', 'Coût des marchandises vendues, octobre'), value: fmt.money0(cc.open + cc.purch - cc.close), prov: 'e', formula: L('Opening inventory + purchases − closing inventory', 'Inventaire d’ouverture + achats − inventaire de clôture'), inputs: [{ label: L('Opening inventory (Sep 27 count)', 'Inventaire d’ouverture (27 sept.)'), v: fmt.money0(cc.open), prov: 'v' }, { op: '+', label: L('Purchases, Oct 1–28 (invoices)', 'Achats, 1–28 oct. (factures)'), v: fmt.money0(cc.purch), prov: 'v' }, { op: '−', label: L('Closing inventory (Oct 25 count + deliveries)', 'Inventaire de clôture (25 oct. + livraisons)'), v: fmt.money0(cc.close), prov: 'e' }, { tot: true, op: '=', label: L('Cost of goods sold', 'Coût des marchandises vendues'), v: fmt.money0(cc.open + cc.purch - cc.close) }], rows: { head: [L('Purchased from', 'Acheté chez'), L('Amount', 'Montant')], body: cc.purchBy.map(([k, x]) => [supN(k), fmt.money0(x)]) }, to: ['purchasing', 'invoices'], toLabel: L('Open invoices', 'Ouvrir les factures') };
  const opx = [[L('Rent', 'Loyer'), a.rent, b.rent, L('Fixed', 'Fixe'), 'v'], [L('Utilities', 'Énergie'), a.util, b.util, L('Mostly fixed', 'Surtout fixe'), 'e'], [L('Delivery commissions', 'Commissions de livraison'), a.other * FR.comm, b.other * FR.comm, L('Moves with delivery sales', 'Suit la livraison'), 'v'], [L('Card processing', 'Traitement des cartes'), a.other * FR.card, b.other * FR.card, L('Moves with sales', 'Suit les ventes'), 'e'], [L('Delivery promotions', 'Promotions'), a.other * FR.promos, b.other * FR.promos, L('Your choice', 'À votre choix'), 'v'], [L('Linen', 'Lingerie'), a.other * FR.linen, b.other * FR.linen, L('Fixed', 'Fixe'), 'v']];
  return (
    <div className="page">
      <FinHead sub={L('Cost of goods, operating expenses and the margins left after each.', 'Coût des marchandises, frais d’exploitation et les marges qui restent.')} />
      <section className="kpis">
        <Metric hero ic="package" label={L('Cost of goods sold', 'Coût des marchandises')} value={fmt.money0(a.cogs)} sub={fmt.pct(a.cogsPct) + ' ' + L('of sales', 'des ventes')} prov="e" onClick={() => calc(P.lab.includes('28') || P.lab.includes('oct') ? cogsD : finDrill('gross', v))} />
        <Metric ic="chart-pie-slice" label={L('Gross margin', 'Marge brute')} value={fmt.pct(a.grossPct)} delta={<Pts v={a.grossPct - b.grossPct} />} cmpLab={P.cmpLab} prov="e" onClick={() => calc(finDrill('gross', v))} />
        <Metric ic="buildings" label={L('Operating expenses', 'Frais d’exploitation')} value={fmt.money0(a.opx)} sub={fmt.pct(a.opxPct) + ' ' + L('of sales', 'des ventes')} prov="e" onClick={() => calc(finDrill('op', v))} />
        <Metric ic="coins" label={L('Operating margin', 'Marge d’exploitation')} value={fmt.pct(a.opPct)} delta={<Pts v={a.opPct - b.opPct} />} cmpLab={P.cmpLab} prov="e" onClick={() => calc(finDrill('op', v))} />
      </section>
      <section className="grid-1-1">
        <div className="panel">
          <div className="panel-head"><div><h3>{L('How October’s cost of goods is calculated', 'Calcul du coût des marchandises d’octobre')}</h3></div><button className="btn btn-ghost" onClick={() => calc(cogsD)}><Icon n="calculator" /></button></div>
          {cogsD.inputs.map((x, i) => <div key={i} className={'ln calc-ln' + (x.tot ? ' tot' : '')}><span><span className="calc-op">{x.op || ''}</span>{x.label}</span><span className="calc-v"><b>{x.v}</b>{x.prov ? <Prov k={x.prov} short /> : null}</span></div>)}
          <div className="dr-label" style={{ marginTop: '.4rem' }}>{L('Purchases by supplier', 'Achats par fournisseur')}</div>
          <HBars items={cc.purchBy.map(([k, x]) => ({ label: supN(k), v: x })).sort((x, y) => y.v - x.v)} fmtv={fmt.money0} />
        </div>
        <div className="panel panel-flush">
          <div className="panel-head pad"><div><h3>{L('Operating expenses', 'Frais d’exploitation')}</h3><p className="muted">{P.lab} · {P.cmpLab}</p></div></div>
          <div className="table-scroll"><table className="table mtable"><thead><tr><th>{L('Expense', 'Dépense')}</th><th className="num">{L('Amount', 'Montant')}</th><th className="num hide-sm">%</th><th className="hide-md">{L('Behaves', 'Comportement')}</th><th className="num">{L('Change', 'Écart')}</th></tr></thead>
            <tbody>{opx.map(([n, x, y, k, pv]) => <tr key={n}><td>{n} <Prov k={pv} short /></td><td className="num tnum">{fmt.money0(x)}</td><td className="num tnum hide-sm">{fmt.pct((x / a.rev) * 100)}</td><td className="muted hide-md">{k}</td><td className="num"><Delta v={v.md(x, y)} invert /></td></tr>)}</tbody></table></div>
        </div>
      </section>
      <div className="panel"><div className="panel-head"><div><h3>{L('Gross and operating margin, 12 months', 'Marges brute et d’exploitation, 12 mois')}</h3></div><div className="legend"><span><i className="dot lc-sw lc-a"></i>{L('Gross', 'Brute')}</span><span><i className="dot lc-sw lc-pos"></i>{L('Operating', 'Exploitation')}</span></div></div><LineChart labels={F.months.map((x) => x.label[lang])} series={[{ name: L('Gross margin', 'Marge brute'), values: mk.map((x) => x.grossPct), tone: 'a' }, { name: L('Operating margin', 'Marge d’exploitation'), values: mk.map((x) => x.opPct), tone: 'pos' }]} fmtv={(x) => fmt.pct(x)} height={200} /></div>
    </div>
  );
}

function FinInvWaste() {
  const v = useFinView(); const { L, lang, fmt, F, O, inv, invMap, waste, calc, go } = v;
  const val = inv.reduce((s, i) => s + i.onHand * i.cost, 0), m = monthsK()[11];
  const cogsDay = m.cogs / 28, doh = val / cogsDay, turn = m.cogs / ((F.cogsCalc.open + F.cogsCalc.close) / 2);
  const cur = waste.filter((w) => w.date >= '2026-10-22').reduce((t, w) => t + invMap[w.ing].cost * w.qty, 0);
  const wks = [[L('Oct 1–7', '1–7 oct.'), 142], [L('Oct 8–14', '8–14 oct.'), 128], [L('Oct 15–21', '15–21 oct.'), 135], [L('Oct 22–28', '22–28 oct.'), cur]];
  const wT = wks.reduce((t, x) => t + x[1], 0);
  const byR = Object.values(waste.filter((w) => w.date >= '2026-10-22').reduce((acc, w) => { acc[w.reason] = acc[w.reason] || { label: O.wasteReasons[w.reason][lang], v: 0 }; acc[w.reason].v += invMap[w.ing].cost * w.qty; return acc; }, {})).sort((x, y) => y.v - x.v);
  const use = useUse();
  const vr = inv.filter((i) => use[i.id]).map((i) => { const t = (use[i.id] / 30) * 28, f = O.actualFactor[i.id] || 1; return { i, v: t * (f - 1) * i.cost, p: (f - 1) * 100 }; }).sort((x, y) => y.v - x.v).slice(0, 6);
  return (
    <div className="page">
      <FinHead sub={L('Money sitting on shelves, money lost between the books and the shelf, and money thrown out.', 'L’argent sur les tablettes, l’argent perdu entre les livres et les tablettes, et l’argent jeté.')} />
      <section className="kpis">
        <Metric hero ic="package" label={L('Inventory value', 'Valeur de l’inventaire')} value={fmt.money0(val)} sub={L('right now', 'en ce moment')} prov="e" onClick={() => calc(finDrill('inv', v))} />
        <Metric ic="calendar-blank" label={L('Days of stock on hand', 'Jours de stock')} value={fmt.num(Math.round(doh * 10) / 10)} sub={L('fresh-food spots aim for 2–5', 'visez 2 à 5 pour du frais')} prov="e" onClick={() => calc({ title: L('Days of stock on hand', 'Jours de stock'), value: fmt.num(Math.round(doh * 10) / 10), prov: 'e', formula: L('Inventory value ÷ average daily cost of goods', 'Valeur de l’inventaire ÷ coût moyen quotidien'), inputs: [{ label: L('Inventory value', 'Valeur'), v: fmt.money0(val), prov: 'e' }, { op: '÷', label: L('Cost of goods per day, October', 'Coût quotidien, octobre'), v: fmt.money0(cogsDay), prov: 'e' }], notes: [L(`Inventory turns about ${turn.toFixed(1)} times a month.`, `L’inventaire tourne environ ${turn.toFixed(1)} fois par mois.`)] })} />
        <Metric ic="trash" label={L('Waste, October', 'Pertes, octobre')} value={fmt.money0(wT)} sub={fmt.pct((wT / m.foodCogs) * 100) + ' ' + L('of food cost', 'du coût alimentaire')} prov="v" onClick={() => go('inventory', { tab: 'waste' })} />
        <Metric ic="arrows-in-line-horizontal" label={L('Count variance, October', 'Écart d’inventaire, octobre')} value={fmt.money0(706)} sub={L('3 full counts', '3 inventaires')} prov="v" onClick={() => calc({ title: L('Count variance', 'Écart d’inventaire'), value: fmt.money0(706), prov: 'v', formula: L('Σ (counted value − expected value) at each full count', 'Σ (valeur comptée − valeur attendue)'), rows: { head: [L('Count', 'Inventaire'), L('By', 'Par'), L('Variance', 'Écart')], body: O.counts.map((c) => [fmt.date(c.date, { weekday: 'short', month: 'short', day: 'numeric' }), c.by, fmt.money(c.varc)]) }, to: ['inventory', 'counts'] })} />
      </section>
      <section className="grid-1-1">
        <div className="panel"><div className="panel-head"><div><h3>{L('Waste by week', 'Pertes par semaine')}</h3><p className="muted">{L('Current week is live from the waste log', 'Semaine en cours : journal des pertes en direct')}</p></div></div><BarChart data={wks.map(([l, x]) => ({ label: l, a: x }))} la={L('Waste', 'Pertes')} fmtv={(x, full) => (full ? fmt.money(x) : fmt.money0(x))} height={160} highlightLast /><div className="dr-label">{L('This week by reason', 'Cette semaine par raison')}</div><HBars items={byR} fmtv={fmt.money0} /></div>
        <div className="panel panel-flush"><div className="panel-head pad"><div><h3>{L('Biggest inventory variances', 'Plus grands écarts')}</h3><p className="muted">{L('Used beyond what recipes and sales explain · Oct 1–28', 'Utilisé au-delà des recettes et ventes · 1–28 oct.')}</p></div><button className="btn btn-ghost" onClick={() => go('inventory', { tab: 'variance' })}><Icon n="arrow-right" /></button></div>
          <div className="table-scroll"><table className="table mtable"><thead><tr><th>{L('Item', 'Article')}</th><th className="num">{L('Over', 'Excès')}</th><th className="num">{L('Cost', 'Coût')}</th></tr></thead><tbody>{vr.map((x) => <tr key={x.i.id}><td className="cell-main">{x.i.name[lang]}</td><td className="num"><Pill tone={x.p > 8 ? 'neg' : 'warn'}>+{fmt.pct(x.p)}</Pill></td><td className="num tnum">{fmt.money0(x.v)}</td></tr>)}</tbody></table></div></div>
      </section>
    </div>
  );
}

function FinSuppliers() {
  const v = useFinView(); const { L, lang, fmt, F, D, inv, calc } = v;
  const use = useUse();
  const idx = (items) => { const b0 = items.reduce((s, i) => s + i.hist[0] * (use[i.id] || 0), 0); return [0, 1, 2, 3, 4, 5].map((t) => (items.reduce((s, i) => s + i.hist[t] * (use[i.id] || 0), 0) / b0) * 100); };
  const used = inv.filter((i) => use[i.id]);
  const sups = D.suppliers.filter((s) => used.some((i) => i.sup === s.id));
  const tones = ['b', 'pos', 'warn', 'neg'];
  const labels = F.months.slice(6).map((m) => m.label[lang]);
  const movers = used.map((i) => ({ i, p: ((i.hist[5] - i.hist[0]) / i.hist[0]) * 100, imp: (i.hist[5] - i.hist[0]) * use[i.id] })).filter((x) => Math.abs(x.p) > 0.1).sort((a, b) => b.imp - a.imp);
  const all = idx(used);
  return (
    <div className="page">
      <FinHead sub={L('How much more (or less) the same basket of ingredients costs than in May.', 'Combien coûte de plus (ou de moins) le même panier d’ingrédients qu’en mai.')} />
      <section className="kpis">
        <Metric hero ic="trend-up" label={L('Ingredient price index', 'Indice des prix')} value={fmt.num(Math.round(all[5] * 10) / 10)} sub={L('May = 100', 'mai = 100')} prov="v" onClick={() => calc({ title: L('Ingredient price index', 'Indice des prix'), value: fmt.num(Math.round(all[5] * 10) / 10), prov: 'v', formula: L('Σ (this month’s price × monthly usage) ÷ Σ (May price × monthly usage) × 100', 'Σ (prix du mois × usage) ÷ Σ (prix de mai × usage) × 100'), notes: [L('Prices come from supplier invoices. Usage comes from recipes × sales, so popular items weigh more.', 'Les prix viennent des factures. L’usage vient des recettes × ventes.')], rows: { head: [L('Month', 'Mois'), L('Index', 'Indice')], body: labels.map((l, t) => [l, fmt.num(Math.round(all[t] * 10) / 10)]) } })} />
        <Metric ic="currency-circle-dollar" label={L('Extra cost per month', 'Coût supplémentaire par mois')} value={fmt.money0(movers.reduce((s, x) => s + x.imp, 0))} sub={L('vs May prices', 'vs prix de mai')} prov="v" onClick={() => calc({ title: L('Extra cost per month vs May', 'Coût supplémentaire vs mai'), value: fmt.money0(movers.reduce((s, x) => s + x.imp, 0)), prov: 'v', formula: L('Σ (October price − May price) × monthly usage', 'Σ (prix d’oct. − prix de mai) × usage mensuel'), rows: { head: [L('Item', 'Article'), L('Change', 'Variation'), L('Per month', 'Par mois')], body: movers.map((x) => [x.i.name[lang], fmt.pct(x.p), fmt.money0(x.imp)]) } })} />
        <Metric ic="arrow-fat-up" label={L('Biggest increase', 'Plus forte hausse')} value={movers[0].i.name[lang]} sub={'+' + fmt.pct(movers[0].p)} prov="v" onClick={() => v.go('purchasing', { tab: 'prices' })} />
      </section>
      <div className="panel">
        <div className="panel-head"><div><h3>{L('Price index by supplier', 'Indice par fournisseur')}</h3><p className="muted">{L('May 2026 = 100', 'mai 2026 = 100')}</p></div><div className="legend"><span><i className="dot lc-sw lc-a"></i>{L('All suppliers', 'Tous')}</span>{sups.slice(0, 4).map((s, i) => <span key={s.id}><i className={'dot lc-sw lc-' + tones[i]}></i>{s.name.split(' ')[0]}</span>)}</div></div>
        <LineChart labels={labels} series={[{ name: L('All suppliers', 'Tous'), values: all, tone: 'a' }, ...sups.slice(0, 4).map((s, i) => ({ name: s.name, values: idx(used.filter((x) => x.sup === s.id)), tone: tones[i], dash: 1 }))]} fmtv={(x) => fmt.num(Math.round(x * 10) / 10)} refLine={100} height={220} every={1} />
      </div>
      <div className="panel panel-flush">
        <div className="panel-head pad"><h3>{L('Price changes since May', 'Variations depuis mai')}</h3></div>
        <div className="table-scroll"><table className="table mtable"><thead><tr><th>{L('Item', 'Article')}</th><th className="hide-sm">{L('Supplier', 'Fournisseur')}</th><th className="num">{L('May', 'Mai')}</th><th className="num">{L('Now', 'Maintenant')}</th><th className="num">{L('Change', 'Variation')}</th><th className="num">{L('Per month', 'Par mois')}</th></tr></thead>
          <tbody>{movers.map((x) => <tr key={x.i.id}><td className="cell-main">{x.i.name[lang]}</td><td className="hide-sm">{D.suppliers.find((s) => s.id === x.i.sup).name}</td><td className="num tnum">{fmt.money(x.i.hist[0])}</td><td className="num tnum">{fmt.money(x.i.hist[5])}</td><td className="num"><Pill tone={x.p > 5 ? 'neg' : x.p > 0 ? 'warn' : 'pos'}>{x.p > 0 ? '+' : ''}{fmt.pct(x.p)}</Pill></td><td className={'num tnum ' + (x.imp > 0 ? 'txt-neg' : 'txt-pos')}>{x.imp > 0 ? '+' : '−'}{fmt.money0(Math.abs(x.imp))}</td></tr>)}</tbody></table></div>
      </div>
    </div>
  );
}

Object.assign(window, { UNCOSTED_PTS, useUse, FinFoodBev, FinLabour, FinPrime, FinCosts, FinInvWaste, FinSuppliers });
