function useLeakActions() {
  const { L, insightState, setInsightState, recipes, setRecipes, toast, fmt } = useMizo();
  const set = (id, s) => { const n = { ...insightState }; if (s) n[id] = s; else delete n[id]; setInsightState(n); };
  const resolve = (x) => {
    if (x.apply === 'price') { setRecipes(recipes.map((r) => (r.id === x.rid ? { ...r, price: x.np } : r))); toast(L(`Price set to ${fmt.money(x.np)}`, `Prix fixé à ${fmt.money(x.np)}`)); }
    else toast(L('Marked resolved — MIZO will confirm in next week’s data', 'Marqué résolu — MIZO confirmera avec les données de la semaine prochaine'));
    set(x.id, 'done');
  };
  return { set, resolve };
}

function LeakCard({ x, open, onToggle }) {
  const { L, lang, fmt, go } = useMizo();
  const { set, resolve } = useLeakActions();
  const c = LEAK_CATS[x.cat], done = x.status === 'resolved' || x.status === 'dismissed';
  return (
    <article className={'leak' + (open ? ' open' : '') + (done ? ' done' : '')}>
      <button className="leak-row" onClick={onToggle} aria-expanded={open}>
        <span className="leak-ic"><Icon n={c[0]} /></span>
        <span className="leak-main"><span className="leak-cat">{L(c[1], c[2])}</span><span className="leak-title">{x.title}</span></span>
        <span className="leak-meta hide-sm"><Conf k={x.conf} /><Prov k={x.prov} /></span>
        <span className="leak-amt">{x.impact >= 1 ? <><b className="tnum">{fmt.money0(x.impact)}</b><span className="muted">{L('/mo', '/mois')}</span></> : null}{x.once ? <span className="leak-once tnum">{fmt.money0(x.once)} {x.cat === 'excess' ? L('tied up', 'immobilisés') : L('one-time', 'ponctuel')}</span> : null}</span>
        <span className="leak-st"><StatusPill s={x.status} /></span>
        <Icon n="caret-down" className="leak-caret" />
      </button>
      {open ? <div className="leak-body">
        <p className="leak-desc">{x.desc}</p>
        <div className="leak-grid">
          <div className="leak-ev">
            <div className="dr-label">{L('Supporting evidence', 'Preuves')}</div>
            <div className="table-scroll"><table className="table mtable calc-table"><thead><tr>{x.ev.head.map((h, i) => <th key={i} className={i ? 'num' : ''}>{h}</th>)}</tr></thead><tbody>{x.ev.body.map((r, i) => <tr key={i}>{r.map((v, j) => <td key={j} className={j ? 'num tnum' : 'cell-main'}>{v}</td>)}</tr>)}</tbody></table></div>
          </div>
          <div className="leak-side">
            <div><div className="dr-label">{L('How the impact is estimated', 'Comment l’impact est estimé')}</div><div className="calc-formula">{x.calc}</div></div>
            <div><div className="dr-label">{L('Data quality', 'Qualité des données')}</div><div className="leak-q"><Conf k={x.conf} /><Prov k={x.prov} /></div></div>
            <div><div className="dr-label">{L('Recommended action', 'Action recommandée')}</div><div className="leak-rec"><Icon n="lightbulb" />{x.action}</div></div>
          </div>
        </div>
        <div className="insight-actions">
          {done ? <button className="btn btn-secondary" onClick={() => set(x.id, null)}><Icon n="arrow-counter-clockwise" />{L('Reopen', 'Rouvrir')}</button> : <>
            <button className="btn btn-primary" onClick={() => resolve(x)}><Icon n="check" />{x.action}</button>
            {x.status !== 'investigating' ? <button className="btn btn-secondary" onClick={() => set(x.id, 'inv')}><Icon n="magnifying-glass" />{L('Investigate', 'Enquêter')}</button> : null}
            {x.to ? <button className="btn btn-secondary" onClick={() => { if (x.status === 'new') set(x.id, 'inv'); go(x.to[0], { tab: x.to[1] }); }}>{L('Open source data', 'Voir les données')}<Icon n="arrow-right" /></button> : null}
            <button className="btn btn-ghost" onClick={() => set(x.id, 'dismissed')}>{L('Not a leak', 'Pas une fuite')}</button>
          </>}
        </div>
      </div> : null}
    </article>
  );
}

function ProfitLeaks() {
  const { L, fmt } = useMizo();
  const I = useIntel();
  const [cat, setCat] = React.useState('all');
  const [view, setView] = React.useState('open');
  const [sort, setSort] = React.useState('impact');
  const [openId, setOpenId] = React.useState(() => I.open.slice().sort((a, b) => b.impact - a.impact)[0]?.id);
  const isOpen = (x) => x.status === 'new' || x.status === 'investigating';
  const byCat = Object.keys(LEAK_CATS).map((k) => ({ k, v: I.open.filter((x) => x.cat === k).reduce((s, x) => s + x.impact, 0) })).filter((x) => x.v > 0).sort((a, b) => b.v - a.v);
  let list = I.leaks.filter((x) => (view === 'open' ? isOpen(x) : view === 'closed' ? !isOpen(x) : true)).filter((x) => cat === 'all' || x.cat === cat);
  list = list.slice().sort((a, b) => (sort === 'impact' ? b.impact + (b.once || 0) / 6 - (a.impact + (a.once || 0) / 6) : CONF_W[b.conf] - CONF_W[a.conf] || b.impact - a.impact));
  const resolvedM = I.leaks.filter((x) => x.status === 'resolved').reduce((s, x) => s + x.impact, 0);
  const verifiedM = I.open.filter((x) => x.prov === 'v').reduce((s, x) => s + x.impact, 0);
  return (
    <div className="page">
      <PageHead sub={L('Every place money is leaving the business that it shouldn’t — found by cross-checking invoices, counts, recipes, waste, schedules and payouts.', 'Chaque endroit où l’argent sort sans raison — trouvé en croisant factures, inventaires, recettes, pertes, horaires et versements.')}><SimTag /></PageHead>
      <section className="panel leak-hero">
        <Meander />
        <div className="leak-hero-top">
          <div>
            <div className="ai-kicker"><Icon n="drop-half-bottom" />{L('Profit leak detector', 'Détecteur de fuites')}</div>
            <div className="leak-hero-big"><b className="tnum">{fmt.money0(I.openTotal)}</b><span>{L('a month in potential leaks', 'par mois de fuites potentielles')}</span></div>
            <p className="muted" style={{ margin: 0 }}>{L(`${I.open.length} open · ${fmt.money0(verifiedM)} backed by verified records, the rest modelled. Plus ${fmt.money0(I.openOnce)} in one-time charges to recover.`, `${I.open.length} ouvertes · ${fmt.money0(verifiedM)} appuyés par des données vérifiées, le reste modélisé. Plus ${fmt.money0(I.openOnce)} de frais ponctuels à récupérer.`)}</p>
          </div>
          <div className="leak-hero-stats">
            <Stat label={L('Annualized', 'Sur un an')} value={fmt.money0(I.openTotal * 12)}>{L('if nothing changes', 'si rien ne change')}</Stat>
            <Stat label={L('Recovered', 'Récupéré')} value={fmt.money0(resolvedM)} tone="pos">{L('a month, resolved leaks', 'par mois, fuites résolues')}</Stat>
          </div>
        </div>
        <div className="leak-stack" role="img" aria-label={L('Leaks by category', 'Fuites par catégorie')}>{byCat.map((x) => <button key={x.k} className={'leak-seg' + (cat === x.k ? ' on' : '')} style={{ flex: x.v }} onClick={() => setCat(cat === x.k ? 'all' : x.k)} title={`${L(LEAK_CATS[x.k][1], LEAK_CATS[x.k][2])} · ${fmt.money0(x.v)}`}></button>)}</div>
        <div className="leak-legend">{byCat.map((x) => <button key={x.k} className={'chip' + (cat === x.k ? ' on' : '')} onClick={() => setCat(cat === x.k ? 'all' : x.k)}><Icon n={LEAK_CATS[x.k][0]} />{L(LEAK_CATS[x.k][1], LEAK_CATS[x.k][2])} <b className="tnum">{fmt.kmoney(x.v)}</b></button>)}</div>
      </section>
      <div className="section-head" style={{ marginBottom: 0 }}>
        <div className="itools">
          <Seg size="sm" value={view} onChange={setView} options={[['open', L('Open', 'Ouvertes')], ['closed', L('Resolved', 'Résolues')], ['all', L('All', 'Toutes')]]} />
          {cat !== 'all' ? <button className="chip on" onClick={() => setCat('all')}>{L(LEAK_CATS[cat][1], LEAK_CATS[cat][2])}<Icon n="x" /></button> : null}
        </div>
        <Seg size="sm" value={sort} onChange={setSort} options={[['impact', L('By impact', 'Par impact')], ['conf', L('By confidence', 'Par confiance')]]} />
      </div>
      <div className="leaks">
        {list.map((x) => <LeakCard key={x.id} x={x} open={openId === x.id} onToggle={() => setOpenId(openId === x.id ? null : x.id)} />)}
        {!list.length ? <div className="empty panel">{view === 'open' ? L('No open leaks here. MIZO re-checks every night.', 'Aucune fuite ouverte. MIZO revérifie chaque nuit.') : L('Nothing resolved yet.', 'Rien de résolu.')}</div> : null}
      </div>
    </div>
  );
}

function intelGrowth(L, fmt) {
  const F = window.MIZO_FIN, O = window.MIZO_OPS, fr = F.bevItems.find((b) => b.id === 'frappe');
  return [
    { id: 'g-pickup', cat: 'growth', ic: 'storefront', impact: O.delivery.uber.gross * 0.1 * (O.delivery.uber.comm / 100), conf: 'low', prov: 'e', urg: 'month', title: L('Move 10% of Uber Eats regulars to direct pickup', 'Amener 10 % des habitués Uber à commander pour emporter'), desc: L(`A bag insert with a pickup code. Each order moved saves the ${O.delivery.uber.comm}% commission.`, `Un carton dans le sac avec un code pour emporter. Chaque commande déplacée évite ${O.delivery.uber.comm} % de commission.`), calc: L(`Uber gross ${fmt.money0(O.delivery.uber.gross)} × 10% × ${O.delivery.uber.comm}%`, `Brut Uber ${fmt.money0(O.delivery.uber.gross)} × 10 % × ${O.delivery.uber.comm} %`), action: L('Design pickup insert', 'Créer le carton'), to: ['sales', 'delivery'] },
    { id: 'g-frappe', cat: 'growth', ic: 'coffee', impact: 100 * (fr.price - fr.cost), conf: 'low', prov: 'e', urg: 'month', title: L('Offer a frappé with every lunch pita', 'Proposer un frappé avec chaque pita du midi'), desc: L(`Frappé keeps ${fmt.money(fr.price - fr.cost)} per glass (${fmt.pct((fr.cost / fr.price) * 100)} cost). 100 more a month is about one extra per lunch.`, `Le frappé rapporte ${fmt.money(fr.price - fr.cost)} par verre (${fmt.pct((fr.cost / fr.price) * 100)} de coût). 100 de plus par mois, environ un par midi.`), calc: L('100 extra × (price − cost)', '100 de plus × (prix − coût)'), action: L('Brief the counter team', 'Informer l’équipe'), to: ['menu', 'engineering'] },
    { id: 'g-rain', cat: 'growth', ic: 'cloud-rain', impact: 0, once: 0.15 * O.forecast[0].rev * 0.35, conf: 'med', prov: 'e', urg: 'now', title: L('Rain Thursday evening — prep for +15% delivery', 'Pluie jeudi soir — prévoir +15 % de livraison'), desc: L('Add one packer 5–9 pm and prep 6 kg more chicken so delivery orders aren’t refused or late.', 'Ajouter un emballeur de 17 h à 21 h et 6 kg de poulet de plus pour ne pas refuser de commandes.'), calc: L('15% × Thursday forecast × 35% delivery share, one evening', '15 % × prévision de jeudi × 35 % de livraison, un soir'), action: L('Add the shift', 'Ajouter le quart'), to: ['team', 'schedule'] },
  ].map((x) => x);
}

function Recommendations() {
  const { L, lang, fmt, insightState, go } = useMizo();
  const I = useIntel();
  const { set, resolve } = useLeakActions();
  const [sort, setSort] = React.useState('priority');
  const [sel, setSel] = React.useState(null);
  const st = (id) => (insightState[id] === 'done' ? 'resolved' : insightState[id] === 'dismissed' ? 'dismissed' : insightState[id] === 'inv' ? 'investigating' : 'new');
  const growth = intelGrowth(L, fmt).map((x) => ({ ...x, status: st(x.id), score: intelScore(x) }));
  const all = [...I.leaks.map((x) => ({ ...x, kind: 'fix' })), ...growth.map((x) => ({ ...x, kind: 'grow' }))];
  const open = all.filter((x) => x.status === 'new' || x.status === 'investigating');
  const plan = all.filter((x) => x.status === 'investigating'), done = all.filter((x) => x.status === 'resolved');
  const key = { priority: (x) => x.score, impact: (x) => x.impact + (x.once || 0) / 6, conf: (x) => CONF_W[x.conf] * 1e6 + x.score, urg: (x) => URG_W[x.urg] * 1e6 + x.score }[sort];
  const list = open.slice().sort((a, b) => key(b) - key(a));
  const maxI = Math.max(...open.map((x) => x.impact + (x.once || 0) / 6), 1);
  const urgL = { now: L('This week', 'Cette semaine'), week: L('Within 2 weeks', 'D’ici 2 semaines'), month: L('This month', 'Ce mois-ci') };
  const s = sel && open.find((x) => x.id === sel);
  return (
    <div className="page">
      <PageHead sub={L('Everything MIZO suggests, fixes and growth ideas together, ranked by monthly impact × confidence × urgency.', 'Toutes les suggestions de MIZO, corrections et idées de croissance, classées par impact × confiance × urgence.')}><SimTag /></PageHead>
      <section className="stats">
        <Stat label={L('Open opportunities', 'Occasions ouvertes')} value={fmt.money0(open.reduce((s, x) => s + x.impact, 0))} tone="acc">{open.length} {L('recommendations, per month', 'recommandations, par mois')}</Stat>
        <Stat label={L('In your plan', 'Dans votre plan')} value={fmt.money0(plan.reduce((s, x) => s + x.impact, 0))}>{plan.length} {L('being worked on', 'en cours')}</Stat>
        <Stat label={L('Done', 'Fait')} value={fmt.money0(done.reduce((s, x) => s + x.impact, 0))} tone="pos">{done.length} {L('resolved, per month', 'résolues, par mois')}</Stat>
      </section>
      <section className="grid-2-1">
        <div className="panel panel-flush">
          <div className="panel-head pad"><div><h3>{L('Ranked for you', 'Classées pour vous')}</h3><p className="muted">{L('Priority = monthly impact × confidence × urgency', 'Priorité = impact mensuel × confiance × urgence')}</p></div>
            <Seg size="sm" value={sort} onChange={setSort} options={[['priority', L('Priority', 'Priorité')], ['impact', L('Impact', 'Impact')], ['conf', L('Confidence', 'Confiance')], ['urg', L('Urgency', 'Urgence')]]} /></div>
          <ol className="recs">{list.map((x, i) => (
            <li key={x.id} className={'rec' + (sel === x.id ? ' on' : '')}>
              <button className="rec-row" onClick={() => setSel(sel === x.id ? null : x.id)}>
                <span className="rec-n tnum">{i + 1}</span>
                <span className="rec-main"><span className="rec-title">{x.kind === 'grow' ? x.title : x.action + ' — ' + x.title.charAt(0).toLowerCase() + x.title.slice(1)}</span>
                  <span className="rec-sub"><span className={'rec-kind ' + x.kind}>{x.kind === 'grow' ? L('Grow', 'Croître') : L('Fix a leak', 'Colmater')}</span><Conf k={x.conf} /><span className="muted"><Icon n="clock" /> {urgL[x.urg]}</span>{x.status === 'investigating' ? <StatusPill s="investigating" /> : null}</span></span>
                <span className="rec-amt">{x.impact >= 1 ? <><b className="tnum">+{fmt.money0(x.impact)}</b><span className="muted">{L('/mo', '/mois')}</span></> : <b className="tnum">{fmt.money0(x.once)}</b>}<span className="rec-bar"><i style={{ width: ((x.impact + (x.once || 0) / 6) / maxI) * 100 + '%' }}></i></span></span>
              </button>
              {sel === x.id ? <div className="rec-body">
                <p className="muted" style={{ margin: 0 }}>{x.desc}</p>
                <div className="calc-formula">{x.calc}</div>
                <div className="insight-actions">
                  <button className="btn btn-primary" onClick={() => (x.kind === 'fix' ? resolve(x) : set(x.id, 'done'))}><Icon n="check" />{x.action}</button>
                  {x.status !== 'investigating' ? <button className="btn btn-secondary" onClick={() => set(x.id, 'inv')}><Icon n="list-plus" />{L('Add to my plan', 'Ajouter à mon plan')}</button> : null}
                  {x.kind === 'fix' ? <button className="btn btn-secondary" onClick={() => go('ai', { tab: 'leaks' })}>{L('See evidence', 'Voir les preuves')}<Icon n="arrow-right" /></button> : x.to ? <button className="btn btn-secondary" onClick={() => go(x.to[0], { tab: x.to[1] })}>{L('Open', 'Ouvrir')}<Icon n="arrow-right" /></button> : null}
                  <button className="btn btn-ghost" onClick={() => set(x.id, 'dismissed')}>{L('Not now', 'Plus tard')}</button>
                </div>
              </div> : null}
            </li>
          ))}</ol>
          {!list.length ? <div className="empty">{L('All caught up.', 'Tout est à jour.')}</div> : null}
        </div>
        <div className="panel">
          <div><h3>{L('Impact vs. confidence', 'Impact vs confiance')}</h3><p className="muted">{L('Top-right first. Larger dots are more urgent.', 'En haut à droite d’abord. Plus gros = plus urgent.')}</p></div>
          <div className="matrix">
            <span className="mx-y">{L('Confidence', 'Confiance')} →</span><span className="mx-x">{L('Monthly impact', 'Impact mensuel')} →</span>
            <span className="mx-q">{L('Do first', 'À faire d’abord')}</span>
            {open.map((x) => { const v = x.impact + (x.once || 0) / 6, px = (Math.log10(Math.max(v, 10)) - 1) / (Math.log10(maxI) - 1 || 1); const j = (x.id.charCodeAt(1) % 5) / 40; return <button key={x.id} className={'mx-dot ' + x.kind + (sel === x.id ? ' on' : '')} style={{ left: 6 + Math.min(1, px) * 86 + '%', bottom: 6 + (CONF_W[x.conf] - 0.4 + j) / 0.7 * 80 + '%', '--s': 10 + URG_W[x.urg] * 8 + 'px' }} onClick={() => setSel(x.id)} title={x.title + ' · ' + fmt.money0(v)}></button>; })}
          </div>
          <div className="legend"><span><i className="dot dot-a"></i>{L('Fix a leak', 'Colmater')}</span><span><i className="dot dot-b"></i>{L('Grow', 'Croître')}</span></div>
          {s ? <div className="suggest"><Icon n="sparkle" /><div><b>{s.title}</b><br /><span className="muted sm">{fmt.money0(s.impact || s.once)} · {urgL[s.urg]}</span></div></div> : null}
        </div>
      </section>
    </div>
  );
}

Object.assign(window, { useLeakActions, LeakCard, ProfitLeaks, Recommendations, intelGrowth });
