function intelOrders(c, I) {
  const { D, O, F, inv, pos, lang, fmt, L } = c;
  const oct = F.days.filter((x) => x.d >= '2026-10-01' && !x.partial), avg = oct.reduce((s, x) => s + x.rev, 0) / oct.length;
  const idx = O.forecast.reduce((s, f) => s + f.rev, 0) / O.forecast.length / avg;
  const onOrd = {}; pos.filter((p) => ['draft', 'pending', 'sent'].includes(p.status)).forEach((p) => p.lines.forEach(([id, q]) => { onOrd[id] = (onOrd[id] || 0) + q; }));
  const lines = inv.map((i) => {
    const u = I.use[i.id] || 0; if (!u) return null;
    const daily = (u / 30) * (O.actualFactor[i.id] || 1) * idx, [lead, cover, exp] = SUP_RHYTHM[i.sup], horizon = lead + cover, shelf = O.meta[i.id] ? O.meta[i.id][3] : 30;
    const safety = daily * cover * (shelf <= 7 ? 0.1 : 0.2), oo = onOrd[i.id] || 0;
    const need = daily * horizon + safety - i.onHand - oo, cap = daily * shelf;
    let q = Math.min(need, cap); if (q <= 0) return { i, daily, horizon, shelf, safety, oo, q: 0, skip: true };
    q = i.unit === 'ea' ? Math.ceil(q / 10) * 10 : Math.ceil(q * 2) / 2;
    const qs = D.quotes[i.id], best = qs ? qs.slice().sort((a, b) => a.p - b.p)[0] : null;
    return { i, daily, horizon, shelf, safety, oo, q, v: q * i.cost, capped: need > cap, lead, exp, alt: best && best.sup !== i.sup && best.p < i.cost ? best : null, cover };
  }).filter(Boolean);
  const order = lines.filter((x) => !x.skip);
  const bySup = D.suppliers.map((s) => ({ s, info: O.supInfo[s.id], lines: order.filter((x) => x.i.sup === s.id), exp: SUP_RHYTHM[s.id][2] })).filter((g) => g.lines.length).map((g) => ({ ...g, total: g.lines.reduce((a, x) => a + x.v, 0) }));
  return { idx, lines, order, bySup, covered: lines.filter((x) => x.skip) };
}

function SmartOrdering() {
  const c = useMizo(); const { L, lang, fmt, D, pos, setPos, toast, go, calc } = c;
  const I = useIntel(), R = intelOrders(c, I);
  const [made, setMade] = React.useState({});
  const [edits, setEdits] = React.useState({});
  const qty = (x) => (edits[x.i.id] != null ? edits[x.i.id] : x.q);
  const create = (g) => {
    const n = Math.max(...pos.map((p) => Number(p.id.split('-')[1]) || 0)) + 1, id = 'PO-' + n;
    setPos([{ id, sup: g.s.id, created: INTEL_TODAY, expected: g.exp, status: 'draft', lines: g.lines.map((x) => [x.i.id, qty(x)]).filter(([, q]) => q > 0), by: 'MIZO', note: { en: 'Drafted by MIZO smart ordering', fr: 'Brouillon par la commande intelligente MIZO' } }, ...pos]);
    setMade({ ...made, [g.s.id]: id }); toast(L(`${id} drafted for ${g.s.name} — waiting for approval`, `${id} préparé pour ${g.s.name} — en attente d’approbation`));
  };
  const why = (x) => calc({ title: x.i.name[lang], value: `${fmt.num(qty(x))} ${x.i.unit}`, prov: 'e', provNote: L('Modelled from forecast and recipes', 'Modélisé selon prévision et recettes'), formula: L('Forecast daily use × days until the delivery after next + safety stock − on hand − already on order, capped by shelf life', 'Usage quotidien prévu × jours jusqu’à la livraison suivante + sécurité − en stock − déjà commandé, plafonné par la durée de conservation'), inputs: [{ label: L('Daily use (recipes × forecast × actual-vs-recipe)', 'Usage quotidien (recettes × prévision × réel/recette)'), v: `${fmt.num(Math.round(x.daily * 100) / 100)} ${x.i.unit}`, prov: 'e' }, { op: '×', label: L(`${x.lead} day(s) to delivery + ${x.cover} days it must cover`, `${x.lead} j avant livraison + ${x.cover} j à couvrir`), v: `${x.horizon} ${L('days', 'j')}` }, { op: '+', label: L('Safety stock', 'Stock de sécurité'), v: fmt.num(Math.round(x.safety * 10) / 10) }, { op: '−', label: L('On hand', 'En stock'), v: fmt.num(x.i.onHand), prov: 'v' }, { op: '−', label: L('Already on order', 'Déjà commandé'), v: fmt.num(x.oo), prov: 'v' }, { tot: true, op: '=', label: L('Suggested (rounded to pack)', 'Suggéré (arrondi)'), v: `${fmt.num(x.q)} ${x.i.unit}` }, { label: L('Shelf life', 'Conservation'), v: `${x.shelf} ${L('days', 'jours')}` }], notes: [x.capped ? L('Capped so nothing expires before it’s used.', 'Plafonné pour éviter les pertes à l’expiration.') : null, x.alt ? L(`${D.suppliers.find((s) => s.id === x.alt.sup).name} quotes ${fmt.money(x.alt.p)} for the same spec.`, `${D.suppliers.find((s) => s.id === x.alt.sup).name} offre ${fmt.money(x.alt.p)} pour le même produit.`) : null].filter(Boolean) });
  const total = R.bySup.reduce((s, g) => s + g.lines.reduce((a, x) => a + qty(x) * x.i.cost, 0), 0);
  return (
    <div className="page">
      <PageHead sub={L('What to order from whom, and why — from stock on hand, the 7-day sales forecast, recipes, shelf life and each supplier’s delivery days.', 'Quoi commander, chez qui et pourquoi — selon le stock, la prévision sur 7 jours, les recettes, la conservation et les jours de livraison.')}><SimTag /></PageHead>
      <SeeAlso k="buying" />
      <section className="stats">
        <Stat label={L('Suggested orders', 'Commandes suggérées')} value={fmt.money0(total)} tone="acc">{R.bySup.length} {L('suppliers', 'fournisseurs')} · {R.order.length} {L('items', 'articles')}</Stat>
        <Stat label={L('Demand next 7 days', 'Demande 7 prochains jours')} value={(R.idx >= 1 ? '+' : '−') + fmt.pct(Math.abs(R.idx - 1) * 100)}>{L('vs October daily average', 'vs moyenne quotidienne d’octobre')}</Stat>
        <Stat label={L('Already covered', 'Déjà couverts')} value={fmt.num(R.covered.length)}>{L('items need nothing this cycle', 'articles sans besoin ce cycle')}</Stat>
      </section>
      {R.bySup.map((g) => { const t = g.lines.reduce((a, x) => a + qty(x) * x.i.cost, 0), under = t < g.info.min; return (
        <div key={g.s.id} className="panel panel-flush">
          <div className="panel-head pad"><div><h3>{g.s.name}</h3><p className="muted">{L('Next delivery', 'Prochaine livraison')} {fmt.date(g.exp, { weekday: 'short', month: 'short', day: 'numeric' })} · {L('order by', 'commander avant')} {g.info.cutoff[lang]} · {L('min.', 'min.')} {fmt.money0(g.info.min)}</p></div>
            <div className="itools"><b className="tnum">{fmt.money(t)}</b>{under ? <Pill tone="warn">{L('Below minimum', 'Sous le minimum')}</Pill> : null}
              {made[g.s.id] ? <button className="btn btn-secondary" onClick={() => go('purchasing', { tab: 'orders' })}><Icon n="check-circle" />{made[g.s.id]}</button> : <button className="btn btn-primary" onClick={() => create(g)}><Icon n="file-plus" />{L('Create draft PO', 'Créer le brouillon')}</button>}</div></div>
          <div className="table-scroll">
            <table className="table mtable">
              <thead><tr><th>{L('Item', 'Article')}</th><th className="num hide-sm">{L('On hand', 'En stock')}</th><th className="num hide-md">{L('Use / day', 'Usage / jour')}</th><th className="num hide-md">{L('Shelf life', 'Conservation')}</th><th className="num">{L('Order', 'Commander')}</th><th className="num hide-sm">{L('Cost', 'Coût')}</th><th></th></tr></thead>
              <tbody>{g.lines.map((x) => (
                <tr key={x.i.id}>
                  <td><div className="cell-main">{x.i.name[lang]}</div><div className="cell-sub">{x.capped ? L('Capped by shelf life', 'Plafonné (conservation)') : x.oo ? L(`${fmt.num(x.oo)} already on order`, `${fmt.num(x.oo)} déjà commandés`) : L(`Covers ${x.horizon} days`, `Couvre ${x.horizon} jours`)}{x.alt ? <> · <span className="txt-acc">{L('cheaper quote available', 'offre moins chère')}</span></> : null}</div></td>
                  <td className="num tnum hide-sm">{fmt.num(x.i.onHand)} {x.i.unit}</td><td className="num tnum hide-md">{fmt.num(Math.round(x.daily * 10) / 10)}</td><td className="num tnum hide-md">{x.shelf} {L('d', 'j')}</td>
                  <td className="num"><input className="input h-in" type="number" min="0" step={x.i.unit === 'ea' ? 10 : 0.5} value={qty(x)} disabled={!!made[g.s.id]} onChange={(e) => setEdits({ ...edits, [x.i.id]: Math.max(0, Number(e.target.value)) })} aria-label={x.i.name[lang]} /> <span className="muted sm">{x.i.unit}</span></td>
                  <td className="num tnum hide-sm">{fmt.money(qty(x) * x.i.cost)}</td>
                  <td className="num"><button className="btn btn-ghost btn-icon" onClick={() => why(x)} aria-label={L('Why this amount', 'Pourquoi cette quantité')} title={L('Why this amount', 'Pourquoi cette quantité')}><Icon n="calculator" /></button></td>
                </tr>
              ))}</tbody>
            </table>
          </div>
        </div>
      ); })}
      <p className="muted sm" style={{ margin: 0 }}><Icon n="info" /> {L('Drafts go to Purchasing → Orders and follow your approval rules. Nothing is sent to a supplier automatically.', 'Les brouillons vont dans Achats → Commandes et suivent vos règles d’approbation. Rien n’est envoyé automatiquement.')}</p>
    </div>
  );
}

function briefData(c, I, kind, key) {
  const { F, O, L, fmt } = c, byD = Object.fromEntries(F.days.map((x) => [x.d, x]));
  if (kind === 'daily') {
    const x = byD[key], p = byD[iAdd(key, -7)], k = finK(fsum([x])), kp = finK(fsum([p])), w = x.w, nx = byD[iAdd(key, 1)];
    return { kind, key, title: fmt.date(key, { weekday: 'long', month: 'long', day: 'numeric' }), sent: L(`Sent ${fmt.date(iAdd(key, 1), { weekday: 'short', month: 'short', day: 'numeric' })} · 7:00`, `Envoyé ${fmt.date(iAdd(key, 1), { weekday: 'short', month: 'short', day: 'numeric' })} · 7 h`), k, kp, cmpLab: L('same day last week', 'même jour la semaine dernière'), next: { lab: nx ? fmt.date(nx.d, { weekday: 'long' }) : '', rev: O.dowRev[(w + 1) % 7] }, rows: [x] };
  }
  const rows = F.days.filter((x) => x.d >= key && x.d <= iAdd(key, 6)), prev = F.days.filter((x) => x.d >= iAdd(key, -7) && x.d <= iAdd(key, -1));
  const k = finK(fsum(rows)), kp = finK(fsum(prev)), best = rows.slice().sort((a, b) => b.rev - a.rev)[0];
  return { kind, key, title: L(`Week of ${fmt.date(key, { month: 'long', day: 'numeric' })}`, `Semaine du ${fmt.date(key, { day: 'numeric', month: 'long' })}`), sent: L(`Sent ${fmt.date(iAdd(key, 7), { weekday: 'short', month: 'short', day: 'numeric' })} · 7:00`, `Envoyé ${fmt.date(iAdd(key, 7), { weekday: 'short', month: 'short', day: 'numeric' })} · 7 h`), k, kp, best, cmpLab: L('previous week', 'semaine précédente'), next: { lab: L('next 7 days', '7 prochains jours'), rev: O.forecast.reduce((s, f) => s + f.rev, 0) }, rows };
}

function Briefings() {
  const c = useMizo(); const { L, lang, fmt, go, toast } = c;
  const I = useIntel(), alerts = useAlerts();
  const [kind, setKind] = React.useState('daily');
  const keys = kind === 'daily' ? ['2026-10-27', '2026-10-26', '2026-10-25', '2026-10-24', '2026-10-23'] : ['2026-10-19', '2026-10-12', '2026-10-05', '2026-09-28'];
  const [sel, setSel] = React.useState({ daily: '2026-10-27', weekly: '2026-10-19' });
  const [sched, setSched] = React.useState({ dEmail: true, dText: false, wEmail: true, wText: true });
  const [mail, setMail] = React.useState(false);
  const b = briefData(c, I, kind, sel[kind]), k = b.k, kp = b.kp, md = (x, y) => (y ? ((x - y) / Math.abs(y)) * 100 : 0);
  const up = k.rev >= kp.rev, top = I.open.slice().sort((x, y) => y.impact - x.impact).slice(0, 3);
  const wk = kind === 'weekly' ? c.F.WK[b.best.w][lang === 'fr' ? 1 : 0] : null;
  const headline = kind === 'daily'
    ? L(`${up ? 'A good' : 'A slower'} ${fmt.date(b.key, { weekday: 'long' })}: ${fmt.money0(k.rev)} in sales, ${up ? 'up' : 'down'} ${fmt.pct(Math.abs(md(k.rev, kp.rev)))} on last week. Labour came in at ${fmt.pct(k.labPct)}.`, `${fmt.date(b.key, { weekday: 'long' })} ${up ? 'solide' : 'plus lent'} : ${fmt.money0(k.rev)} de ventes, ${up ? 'en hausse' : 'en baisse'} de ${fmt.pct(Math.abs(md(k.rev, kp.rev)))}. Main-d’œuvre à ${fmt.pct(k.labPct)}.`)
    : L(`You sold ${fmt.money0(k.rev)} this week, ${up ? 'up' : 'down'} ${fmt.pct(Math.abs(md(k.rev, kp.rev)))}. Estimated operating profit was ${fmt.money0(k.op)} (${fmt.pct(k.opPct)}). ${wk} was the best day.`, `Ventes de ${fmt.money0(k.rev)} cette semaine, ${up ? 'en hausse' : 'en baisse'} de ${fmt.pct(Math.abs(md(k.rev, kp.rev)))}. Profit d’exploitation estimé : ${fmt.money0(k.op)} (${fmt.pct(k.opPct)}). Meilleure journée : ${wk}.`);
  const good = [k.avgTk > kp.avgTk ? L(`Average ticket rose to ${fmt.money(k.avgTk)} (from ${fmt.money(kp.avgTk)}).`, `Addition moyenne en hausse à ${fmt.money(k.avgTk)} (de ${fmt.money(kp.avgTk)}).`) : null, k.labPct < kp.labPct ? L(`Labour improved ${fmt.num(Math.round((kp.labPct - k.labPct) * 10) / 10)} pts.`, `Main-d’œuvre améliorée de ${fmt.num(Math.round((kp.labPct - k.labPct) * 10) / 10)} pts.`) : null, k.foodPct < kp.foodPct ? L(`Food cost eased to ${fmt.pct(k.foodPct)}.`, `Coût alimentaire en baisse à ${fmt.pct(k.foodPct)}.`) : null, up ? L(`${fmt.num(Math.round(k.tk))} tickets, ${fmt.num(Math.round(k.tk - kp.tk))} more than ${b.cmpLab}.`, `${fmt.num(Math.round(k.tk))} additions, ${fmt.num(Math.round(k.tk - kp.tk))} de plus.`) : null].filter(Boolean);
  const watch = [k.labPct > 31 ? L(`Labour at ${fmt.pct(k.labPct)} is above your 31% line.`, `Main-d’œuvre à ${fmt.pct(k.labPct)}, au-dessus de 31 %.`) : null, k.foodPct > 30 ? L(`Food cost ${fmt.pct(k.foodPct)} is above the ${c.target}% target.`, `Coût alimentaire ${fmt.pct(k.foodPct)} au-dessus de la cible de ${c.target} %.`) : null, ...alerts.slice(0, 3).map((a) => a.text)].filter(Boolean).slice(0, 4);
  const kpis = [[L('Sales', 'Ventes'), fmt.money0(k.rev), <Delta v={md(k.rev, kp.rev)} />, 'v'], [L('Tickets · avg', 'Additions · moy.'), `${fmt.num(Math.round(k.tk))} · ${fmt.money(k.avgTk)}`, <Delta v={md(k.avgTk, kp.avgTk)} />, 'v'], [L('Labour', 'Main-d’œuvre'), fmt.pct(k.labPct), <Pts v={k.labPct - kp.labPct} invert />, 'e'], [L('Operating profit (est.)', 'Profit d’exploitation (est.)'), fmt.money0(k.op), <Delta v={md(k.op, kp.op)} />, 'e']];
  return (
    <div className="page">
      <PageHead sub={L('A short written summary of the business, waiting for you each morning and every Monday.', 'Un court résumé écrit de l’entreprise, chaque matin et chaque lundi.')}><Seg size="sm" value={kind} onChange={setKind} options={[['daily', L('Daily', 'Quotidien')], ['weekly', L('Weekly', 'Hebdomadaire')]]} /></PageHead>
      <section className="grid-1-2 brief-wrap">
        <div className="panel brief-list">
          <h3>{L('Archive', 'Archives')}</h3>
          {keys.map((key) => { const x = briefData(c, I, kind, key); return <button key={key} className={'brief-item' + (sel[kind] === key ? ' on' : '')} onClick={() => setSel({ ...sel, [kind]: key })}><span><b>{x.title}</b><span className="muted sm">{x.sent}</span></span><span className="tnum">{fmt.kmoney(x.k.rev)}</span></button>; })}
          <div className="dr-label" style={{ marginTop: '.5rem' }}>{L('Delivery', 'Envoi')}</div>
          <div className="set-row"><div><div>{L('Daily · 7:00 am', 'Quotidien · 7 h')}</div><div className="muted sm">{L('Email', 'Courriel')}{sched.dText ? ' + ' + L('text', 'texto') : ''}</div></div><Toggle on={sched.dText} label={L('Daily by text', 'Quotidien par texto')} onChange={(v) => setSched({ ...sched, dText: v })} /></div>
          <div className="set-row"><div><div>{L('Weekly · Monday 7:00 am', 'Hebdo · lundi 7 h')}</div><div className="muted sm">{L('Email', 'Courriel')}{sched.wText ? ' + ' + L('text', 'texto') : ''}</div></div><Toggle on={sched.wText} label={L('Weekly by text', 'Hebdo par texto')} onChange={(v) => setSched({ ...sched, wText: v })} /></div>
          <button className="btn btn-ghost" onClick={() => go('settings', { tab: 'notifications' })}>{L('All notification settings', 'Tous les réglages')}<Icon n="arrow-right" /></button>
        </div>
        <article className="panel brief">
          <Meander />
          <div className="brief-top"><div className="ai-kicker"><Icon n="newspaper" />{kind === 'daily' ? L('Daily briefing', 'Résumé quotidien') : L('Weekly briefing', 'Résumé hebdomadaire')}</div><SimTag /></div>
          <div><h2 className="brief-title">{b.title}</h2><span className="muted sm">{b.sent} · {L('to', 'à')} eleni@souvlakivillage.ca</span></div>
          <p className="brief-lede">{headline}</p>
          <div className="brief-kpis">{kpis.map(([n, v, d, p]) => <div key={n}><span className="muted sm">{n} <Prov k={p} short /></span><b className="tnum">{v}</b><span className="sm">{d} <span className="muted">{b.cmpLab}</span></span></div>)}</div>
          {kind === 'weekly' ? <div><div className="dr-label">{L('Day by day', 'Jour par jour')}</div><BarChart data={b.rows.map((x) => { const kk = finK(fsum([x])); return { label: c.F.WK[x.w][lang === 'fr' ? 1 : 0], a: kk.rev, b: kk.rev - kk.op }; })} la={L('Sales', 'Ventes')} lb={L('Costs', 'Coûts')} fmtv={(v, full) => (full ? fmt.money0(v) : fmt.kmoney(v))} height={150} /></div> : null}
          <div className="brief-cols">
            <div><div className="dr-label"><Icon n="thumbs-up" /> {L('What went well', 'Ce qui a bien été')}</div><ul className="brief-ul">{(good.length ? good : [L('Steady — no notable gains.', 'Stable — pas de gain notable.')]).map((t, i) => <li key={i}>{t}</li>)}</ul></div>
            <div><div className="dr-label"><Icon n="eye" /> {L('Keep an eye on', 'À surveiller')}</div><ul className="brief-ul">{watch.map((t, i) => <li key={i}>{t}</li>)}</ul></div>
          </div>
          <div><div className="dr-label"><Icon n="drop-half-bottom" /> {L('Top profit leaks still open', 'Principales fuites ouvertes')}</div>
            <ul className="ai-list">{top.map((x) => <li key={x.id}><span className="ai-amt">{fmt.money0(x.impact)}</span><span>{x.title}</span></li>)}</ul></div>
          <div className="suggest"><Icon n="calendar-check" /><div>{L(`${kind === 'daily' ? 'Expect about' : 'Forecast for the'} ${kind === 'daily' ? fmt.money0(b.next.rev) + ' ' + b.next.lab : b.next.lab + ': ' + fmt.money0(b.next.rev)}. ${top[0] ? 'One thing to do: ' + top[0].action.toLowerCase() + '.' : ''}`, `${kind === 'daily' ? 'Prévu environ ' + fmt.money0(b.next.rev) + ' ' + b.next.lab : 'Prévision ' + b.next.lab + ' : ' + fmt.money0(b.next.rev)}. ${top[0] ? 'À faire : ' + top[0].action.toLowerCase() + '.' : ''}`)}</div></div>
          <div className="insight-actions">
            <button className="btn btn-primary" onClick={() => go('ai', { tab: 'leaks' })}>{L('Review leaks', 'Voir les fuites')}<Icon n="arrow-right" /></button>
            <button className="btn btn-secondary" onClick={() => go('finance', { tab: kind === 'daily' ? 'revenue' : 'pnl' })}>{L('Full numbers', 'Tous les chiffres')}</button>
            <button className="btn btn-ghost" onClick={() => setMail(true)}><Icon n="paper-plane-tilt" />{L('Send me a test', 'M’envoyer un test')}</button>
          </div>
        </article>
      </section>
      <SimSendModal open={mail} onClose={() => setMail(false)} title={L('Send a test briefing', 'Envoyer un résumé test')} to="eleni@souvlakivillage.ca" subject={(kind === 'daily' ? L('Your daily briefing — ', 'Votre résumé quotidien — ') : L('Your weekly briefing — ', 'Votre résumé hebdo — ')) + b.title} lines={[headline, ...good.slice(0, 2), top[0] ? L('Top leak: ', 'Fuite principale : ') + top[0].title : '']} />
    </div>
  );
}

Object.assign(window, { intelOrders, SmartOrdering, briefData, Briefings });
