// =============================================================
// Dashboard — overview, KPIs, CA curve, pipeline viz
// =============================================================

const Dashboard = ({ state, navigate, actions }) => {
  const { sales, purchases, shipments, stockSeries, sealed, topups, categories, bankMovements = [] } = state;
  const [bankOpen, setBankOpen] = useState(false);

  // ---- KPI calcs ----
  const ca = sales.reduce((a, s) => a + s.eur, 0);
  const cogs = sales.reduce((a, s) => a + (s.cost || 0), 0);
  const margin = ca - cogs;
  const marginPct = ca ? (margin / ca) * 100 : 0;

  const stockValue =
    stockSeries.reduce((a, s) => a + (s.np + s.nh + s.h) * s.unit_cost, 0) +
    sealed.reduce((a, x) => a + x.qty * x.cost, 0);

  const stockUnits =
    stockSeries.reduce((a, s) => a + s.np + s.nh + s.h, 0) +
    sealed.reduce((a, x) => a + x.qty, 0);

  const inTransitShipments = shipments.filter(s => s.status === "in_transit" || s.status === "created");
  const inTransitJpy = purchases.filter(p => inTransitShipments.find(s => s.id === p.ship))
    .reduce((a, p) => a + p.jpy + p.port_jp, 0);

  const totalTopupsJpy = topups.reduce((a, t) => a + t.jpy, 0);

  // ---- Taux JPY/EUR : reels depuis les topups confirmes ----
  // Doit etre defini AVANT le pipeline qui s'en sert
  const ratedTopups = [...topups]
    .filter(t => t.rate && t.date)
    .sort((a, b) => a.date.localeCompare(b.date));
  const lastTopup = ratedTopups[ratedTopups.length - 1];
  const currentEffectiveRate = lastTopup?.rate || state.currentRate || 0;
  const lastTopupDate = lastTopup?.date;
  const rateSeries = ratedTopups.map(t => t.rate);
  const rateMin = rateSeries.length ? Math.min(...rateSeries) : null;
  const rateMax = rateSeries.length ? Math.max(...rateSeries) : null;
  const firstRateDate = ratedTopups[0]?.date;

  // ---- Investi (cash sorti) : topups EUR Mercari + achats manuels EUR ----
  const mercariShipIds = new Set(shipments.filter(s => !s.source).map(s => s.id));
  const manualShipIds  = new Set(shipments.filter(s =>  s.source).map(s => s.id));
  const mercariTopupsEur = topups.filter(t => t.eur).reduce((a, t) => a + t.eur, 0);
  const manualPurchasesEur = purchases
    .filter(p => manualShipIds.has(p.ship))
    .reduce((a, p) => a + (p.eur || 0), 0);
  const totalInvested = mercariTopupsEur + manualPurchasesEur;

  // ---- Pipeline : valeur EUR a chaque etape du tunnel ----
  // Helper : EUR estime d'un achat (deja en eur si rempli, sinon converti via rate)
  const purchaseEur = (p) => {
    if (p.eur && p.eur > 0) return p.eur;
    const sh = shipments.find(s => s.id === p.ship);
    // pour les commandes EUR/USD le rate vaut 1, donc on retombe sur le jpy brut (=0 normalement)
    const rate = sh?.rate || currentEffectiveRate || 170;
    if (!rate || rate <= 0) return 0;
    return ((p.jpy || 0) + (p.port_jp || 0) + (p.zm_fee || 0)) / rate;
  };
  const pipeOrdered = purchases.reduce((a, p) => a + purchaseEur(p), 0);
  const receivedShipIds = new Set(
    shipments.filter(s => s.status === "received" || s.status === "delivered").map(s => s.id)
  );
  const pipeReceived = purchases
    .filter(p => receivedShipIds.has(p.ship))
    .reduce((a, p) => a + purchaseEur(p), 0);
  // Distribues = stock_state = "available" (Mercari workflow) OU achat manuel (toujours distribue direct)
  const pipeDistributed = purchases
    .filter(p => p.stock_state === "available" || manualShipIds.has(p.ship))
    .reduce((a, p) => a + purchaseEur(p), 0);
  const pipeSold = ca;  // = CA encaisse
  // Position cash = CA - Achats commandes
  // Negative = il manque ca pour rentrer dans les frais de TOUS les achats
  // Positive = les ventes ont deja couvert tous les achats commandes
  const pipeCashPos = pipeSold - pipeOrdered;

  // ---- CA evolution ----
  const sortedSales = [...sales].filter(s => s.platform !== "adjustment").sort((a, b) => a.date.localeCompare(b.date));
  const months = {};
  sortedSales.forEach(s => {
    const m = s.date.slice(0, 7);
    if (!months[m]) months[m] = { date: m, ca: 0, margin: 0, count: 0 };
    months[m].ca += s.eur;
    months[m].margin += s.eur - (s.cost || 0);
    months[m].count += 1;
  });
  const monthly = Object.values(months);

  // Cumulative
  let cumCa = 0;
  const cumulative = monthly.map(m => {
    cumCa += m.ca;
    return { ...m, cumCa };
  });

  // ---- Recent sales ----
  const recentSales = [...sales].sort((a, b) => b.date.localeCompare(a.date)).slice(0, 6);

  // ---- Solde Boursorama dynamique ----
  // Ancre recalibree 2026-06-06 : solde reel Boursorama 430.72 EUR (= SOLDE FINAL Excel Compte Bourso).
  // ANCRE = 430.72 - ca(2903.91) + achats(3951.07) = 1477.88.
  // KPI suit en live (vente +, achat -).
  // NB : "Total Boursorama" = solde business pur (achats/ventes uniquement), les mouvements manuels
  // (ajout/retrait) ne le modifient PAS. Ils pilotent la dette et le "Solde reel" (compte physique) a part.
  const BOURSO_ANCRE = 1477.88;
  const MISE_INITIALE = 1600;
  const DETTE_BASE = 228.56;
  const totalAchatsEur = purchases.reduce((a, p) => a + purchaseEur(p), 0);
  const BOURSO_SOLDE = BOURSO_ANCRE + ca - totalAchatsEur;
  // Mouvements manuels (compte Boursorama) : un ajout gonfle le solde reel et reduit la dette,
  // un retrait fait l'inverse. La dette peut passer sous zero (surplus), on l'affiche telle quelle.
  const bankAjouts = bankMovements.filter(m => m.kind === "add").reduce((a, m) => a + (m.amount_eur || 0), 0);
  const bankRetraits = bankMovements.filter(m => m.kind === "withdraw").reduce((a, m) => a + (m.amount_eur || 0), 0);
  // ancre recalibree 2026-07-07 : solde reel Boursorama 202.07 EUR (ANCRE = 202.07 - ca(2903.91) + achats(3951.07))
  const SOLDE_REEL_ANCRE = 1249.23;
  const SOLDE_REEL = SOLDE_REEL_ANCRE + ca - totalAchatsEur + bankAjouts - bankRetraits;
  const DETTE = DETTE_BASE + bankRetraits - bankAjouts;

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Vue d'ensemble</h1>
          <div className="page-sub">Compta business Pokémon · {sales.length} ventes · {shipments.length} commandes · {purchases.length} achats</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-primary" onClick={() => navigate("sales", { compose: true })}>
            <Icon name="plus" /> Nouvelle vente
          </button>
        </div>
      </div>

      {/* KPIs */}
      <div className="kpi-grid">
        <Kpi label="Total Boursorama" value={BOURSO_SOLDE} unit="€"
             meta={`Mise initiale ${fmtEUR(MISE_INITIALE, { decimals: 0 })} € · Solde réel ${fmtEUR(SOLDE_REEL)} € · Dette ${fmtEUR(DETTE)} €`}
             onClick={() => setBankOpen(true)} />
        <Kpi label="CA encaissé" value={ca} unit="€"
             meta={`${sales.length} ventes`} />
        <Kpi label="Marge sur ventes" value={margin} unit="€"
             delta={ca ? `${marginPct.toFixed(1)} %` : ""}
             deltaPos={margin >= 0}
             meta={`coût marchandises ${fmtEUR(cogs, { decimals: 0 })} €`} />
        <Kpi label="Stock à liquider" value={stockValue} unit="€"
             meta={`${fmtInt(stockUnits)} unités · ${stockSeries.length} séries`}
             accent />
      </div>

      {/* Pipeline */}
      <div className="card" style={{ marginTop: 16 }}>
        <div className="card-head">
          <div>
            <div className="card-title">Pipeline business</div>
            <div className="card-sub">Où l'argent est bloqué dans le tunnel achat → vente</div>
          </div>
          <span className="tag tag-ghost mono">tout en €</span>
        </div>
        <div className="pipeline">
          <PipelineStep n="01" title="Achats commandés"
                        value={`${fmtEUR(pipeOrdered, { decimals: 0 })} €`}
                        meta={`${purchases.length} items, toutes sources`} />
          <PipelineStep n="02" title="Reçus en France"
                        value={`${fmtEUR(pipeReceived, { decimals: 0 })} €`}
                        meta={`${receivedShipIds.size} colis livrés`} />
          <PipelineStep n="03" title="Distribués au stock"
                        value={`${fmtEUR(pipeDistributed, { decimals: 0 })} €`}
                        meta={`${fmtInt(stockUnits)} unités dispo`}
                        highlight />
          <PipelineStep n="04" title="Vendus (CA)"
                        value={`${fmtEUR(pipeSold, { decimals: 0 })} €`}
                        meta={`${sales.length} ventes`} />
          <PipelineStep n="05" title="Position cash"
                        value={`${pipeCashPos >= 0 ? "+" : ""}${fmtEUR(pipeCashPos, { decimals: 0 })} €`}
                        meta={pipeCashPos >= 0 ? "rentré dans les frais" : "à combler"} />
        </div>
      </div>

      {/* Chart + Recent */}
      <div className="dash-grid">
        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title">Évolution du chiffre d'affaires</div>
              <div className="card-sub">Mensuel · cumulé · {sortedSales.length} ventes</div>
            </div>
            <div className="tabs" style={{ alignSelf: "center" }}>
              <button className="active">Mensuel</button>
              <button>Cumulé</button>
            </div>
          </div>
          <RevenueChart data={cumulative} />
        </div>
        <div className="card">
          <div className="card-head">
            <div>
              <div className="card-title">Ventes récentes</div>
              <div className="card-sub">6 dernières</div>
            </div>
            <button className="btn btn-ghost btn-sm" onClick={() => navigate("sales")}>
              Tout voir <Icon name="chev" />
            </button>
          </div>
          <div>
            {recentSales.map(s => {
              const cat = categories.find(c => c.id === s.cat);
              const m = s.eur - (s.cost || 0);
              return (
                <div key={s.id} style={{
                  padding: "10px 20px", borderBottom: "1px solid var(--line-2)",
                  display: "grid", gridTemplateColumns: "1fr auto", gap: 8, alignItems: "center"
                }}>
                  <div>
                    <div style={{ fontSize: 13, fontWeight: 500 }}>{s.title}</div>
                    <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 2 }}>
                      {fmtDate(s.date)} · {s.platform === "adjustment" ? "Ajustement" : s.platform} · {cat?.name || "—"}
                    </div>
                  </div>
                  <div style={{ textAlign: "right" }}>
                    <div className="mono" style={{ fontSize: 13, fontWeight: 500 }}>
                      <Money eur={s.eur} />
                    </div>
                    <div className="mono" style={{ fontSize: 11, color: m >= 0 ? "var(--pos)" : "var(--neg)", marginTop: 1 }}>
                      {m >= 0 ? "+" : ""}{fmtEUR(m)} €
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </div>

      {/* Bottom row */}
      <div className="dash-grid-3">
        <div className="card">
          <div className="card-head">
            <div className="card-title">Stock par série · top 6</div>
            <div className="card-sub">{fmtInt(stockUnits)} unités</div>
          </div>
          <div style={{ padding: "8px 0" }}>
            {[...stockSeries].sort((a, b) => (b.np + b.nh + b.h) - (a.np + a.nh + a.h)).slice(0, 6).map(s => {
              const tot = s.np + s.nh + s.h;
              return (
                <div key={s.short} style={{ padding: "9px 20px", display: "grid", gridTemplateColumns: "1fr auto auto", gap: 14, alignItems: "center", borderBottom: "1px solid var(--line-2)" }}>
                  <div>
                    <div style={{ fontSize: 13, fontWeight: 500 }}>{s.name}</div>
                    <div style={{ height: 4, background: "var(--line-2)", borderRadius: 2, marginTop: 6, display: "flex", overflow: "hidden", width: 140 }}>
                      <div style={{ width: `${(s.np / tot) * 100}%`, background: "var(--ink-4)" }}></div>
                      <div style={{ width: `${(s.nh / tot) * 100}%`, background: "var(--accent-2)" }}></div>
                      <div style={{ width: `${(s.h / tot) * 100}%`, background: "var(--pos)" }}></div>
                    </div>
                  </div>
                  <div className="mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>
                    {s.np > 0 && <span>{s.np}NP </span>}
                    {s.nh > 0 && <span>{s.nh}NH </span>}
                    {s.h > 0 && <span>{s.h}H</span>}
                  </div>
                  <div className="mono" style={{ fontSize: 14, fontWeight: 500, width: 30, textAlign: "right" }}>{tot}</div>
                </div>
              );
            })}
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <div className="card-title">Colis en cours</div>
            <div className="card-sub">à recevoir</div>
          </div>
          <div style={{ padding: "8px 0" }}>
            {inTransitShipments.map(s => {
              const items = purchases.filter(p => p.ship === s.id);
              const totalJpy = items.reduce((a, p) => a + (p.jpy || 0) + (p.port_jp || 0) + (p.zm_fee || 0), 0) + (s.port_jpy || 0) + Math.round((s.duty_eur || 0) * s.rate);
              return (
                <div key={s.id} style={{ padding: "12px 20px", borderBottom: "1px solid var(--line-2)" }}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                      <Icon name="truck" />
                      <span style={{ fontWeight: 500, fontSize: 13 }}>Colis #{s.displayNum || s.id}</span>
                      <StatusPill status={s.status} />
                    </div>
                    <span className="mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>{s.method}</span>
                  </div>
                  <div style={{ marginTop: 8, display: "flex", justifyContent: "space-between", fontSize: 12 }}>
                    <span style={{ color: "var(--ink-3)" }}>{items.length} achats · {fmtDate(s.date)}</span>
                    <span className="mono">¥{fmtJPY(totalJpy)} · {fmtEUR(totalJpy / s.rate, { decimals: 0 })} €</span>
                  </div>
                </div>
              );
            })}
            {inTransitShipments.length === 0 && <div className="empty">Aucun colis en transit</div>}
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <div className="card-title">Taux JPY/EUR effectif</div>
            <div className="card-sub">par rechargement</div>
          </div>
          <div style={{ padding: "16px 20px" }}>
            <div className="mono" style={{ fontSize: 28, fontWeight: 500, letterSpacing: "-0.02em" }}>
              {currentEffectiveRate ? currentEffectiveRate.toFixed(2) : "—"}
            </div>
            <div style={{ fontSize: 11.5, color: "var(--ink-3)", marginTop: 2 }}>
              ¥ pour 1 € · {lastTopupDate ? `dernier rechargement ${fmtDate(lastTopupDate)}` : "aucun rechargement"}
            </div>
            {rateSeries.length > 1 && (
              <React.Fragment>
                <div style={{ marginTop: 16 }}>
                  <Sparkline data={rateSeries} />
                </div>
                <div style={{ display: "flex", justifyContent: "space-between", marginTop: 6, fontSize: 11, color: "var(--ink-3)", fontFamily: "var(--font-mono)" }}>
                  <span>{rateMin.toFixed(2)} · {fmtDate(firstRateDate)}</span>
                  <span>{rateMax.toFixed(2)} · {fmtDate(lastTopupDate)}</span>
                </div>
              </React.Fragment>
            )}
          </div>
        </div>
      </div>

      {bankOpen && (
        <BankDrawer
          bankMovements={bankMovements}
          solde={BOURSO_SOLDE}
          soldeReel={SOLDE_REEL}
          dette={DETTE}
          miseInitiale={MISE_INITIALE}
          actions={actions}
          onClose={() => setBankOpen(false)}
        />
      )}
    </div>
  );
};

// ---------- KPI card ----------
const Kpi = ({ label, value, unit, delta, deltaPos, meta, accent, onClick }) => (
  <div className={`kpi${onClick ? " kpi-clickable" : ""}`} onClick={onClick}>
    <div className="kpi-label">{label}</div>
    <div className="kpi-value" style={accent ? { color: "var(--accent)" } : null}>
      {fmtEUR(value, { decimals: value > 1000 ? 0 : 2 })} <span className="unit">{unit}</span>
    </div>
    <div className="kpi-meta">
      {delta && <span className={`delta ${deltaPos ? "pos" : "neg"}`}>{deltaPos && !delta.startsWith("+") ? "" : ""}{delta}</span>}
      {delta && meta && <span>·</span>}
      {meta && <span>{meta}</span>}
    </div>
  </div>
);

// ---------- Bank movement drawer (ajout/retrait compte Boursorama) ----------
const BankDrawer = ({ bankMovements, solde, soldeReel, dette, miseInitiale, actions, onClose }) => {
  const [amount, setAmount] = useState("");
  const [note, setNote] = useState("");

  // virgule decimale francaise ("12,5") -> point avant conversion, sinon Number() renvoie NaN
  const amountNum = Number(String(amount).replace(",", ".")) || 0;
  const canSubmit = amountNum > 0;

  const submit = (kind) => {
    if (!canSubmit) return;
    actions.addBankMovement(kind, amountNum, note.trim() || null);
    setAmount("");
    setNote("");
  };

  const sortedMovements = [...bankMovements].sort((a, b) => (b.created_at || "").localeCompare(a.created_at || ""));

  return (
    <Drawer open onClose={onClose}
      title="Compte Boursorama"
      sub="Ajouter ou retirer de l'argent"
    >
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10, marginBottom: 16 }}>
        <div className="field">
          <label>Total Boursorama</label>
          <div className="mono" style={{ fontSize: 18, fontWeight: 500, marginTop: 4 }}>{fmtEUR(solde)} €</div>
        </div>
        <div className="field">
          <label>Solde réel</label>
          <div className="mono" style={{ fontSize: 18, fontWeight: 500, marginTop: 4 }}>{fmtEUR(soldeReel)} €</div>
        </div>
        <div className="field">
          <label>Dette actuelle</label>
          <div className="mono" style={{ fontSize: 18, fontWeight: 500, marginTop: 4, color: dette > 0 ? "var(--neg)" : "var(--pos)" }}>
            {fmtEUR(dette)} €
          </div>
        </div>
        <div className="field">
          <label>Mise initiale</label>
          <div className="mono" style={{ fontSize: 18, fontWeight: 500, marginTop: 4 }}>{fmtEUR(miseInitiale, { decimals: 0 })} €</div>
        </div>
      </div>

      <div className="field">
        <label>Montant</label>
        <div className="input-suffix-wrap">
          <input className="input mono" type="number" step="0.01" min="0" placeholder="0.00"
                 value={amount} onChange={e => setAmount(e.target.value)} />
          <span className="input-suffix">€</span>
        </div>
      </div>
      <div className="field" style={{ marginTop: 10 }}>
        <label>Note</label>
        <input className="input" placeholder="Motif (optionnel)" value={note} onChange={e => setNote(e.target.value)} />
      </div>

      <div style={{ display: "flex", gap: 8, marginTop: 14 }}>
        <button className="btn btn-primary" style={{ flex: 1 }} disabled={!canSubmit} onClick={() => submit("add")}>
          <Icon name="plus" /> Ajouter
        </button>
        <button className="btn btn-danger" style={{ flex: 1 }} disabled={!canSubmit} onClick={() => submit("withdraw")}>
          <Icon name="minus" /> Retirer
        </button>
      </div>

      <div className="subhead" style={{ marginTop: 22 }}><h3>Historique</h3></div>
      {sortedMovements.length === 0 ? (
        <div className="empty">Aucun mouvement</div>
      ) : (
        <div>
          {sortedMovements.map(m => (
            <div key={m.id} style={{
              padding: "10px 0", borderBottom: "1px solid var(--line-2)",
              display: "grid", gridTemplateColumns: "1fr auto auto", gap: 10, alignItems: "center"
            }}>
              <div>
                <div style={{ fontSize: 13 }}>{m.note || (m.kind === "add" ? "Ajout" : "Retrait")}</div>
                <div style={{ fontSize: 11, color: "var(--ink-3)", marginTop: 2 }}>{fmtDate(m.created_at)}</div>
              </div>
              <div className="mono" style={{ fontSize: 13, color: m.kind === "add" ? "var(--pos)" : "var(--neg)" }}>
                {m.kind === "add" ? "+" : "−"}{fmtEUR(m.amount_eur)} €
              </div>
              <button className="btn btn-ghost btn-icon" onClick={() => actions.deleteBankMovement(m.id)}>
                <Icon name="trash" />
              </button>
            </div>
          ))}
        </div>
      )}
    </Drawer>
  );
};

// ---------- Pipeline step ----------
const PipelineStep = ({ n, title, value, meta, highlight }) => (
  <div className={`pipeline-step ${highlight ? "highlight" : ""}`}>
    <div className="ps-num">STEP {n}</div>
    <div className="ps-title">{title}</div>
    <div className="ps-val">{value}</div>
    <div className="ps-meta">{meta}</div>
    <div className="pipeline-arrow"></div>
  </div>
);

// ---------- Revenue chart (custom SVG, hover-aware) ----------
const RevenueChart = ({ data }) => {
  const [hover, setHover] = useState(null);
  const wrapRef = useRef(null);

  const W = 760, H = 240;
  const P = { l: 44, r: 16, t: 16, b: 28 };
  const innerW = W - P.l - P.r;
  const innerH = H - P.t - P.b;

  if (!data.length) return <div className="empty">Pas de données</div>;

  const maxCa = Math.max(...data.map(d => d.ca));
  const maxCum = Math.max(...data.map(d => d.cumCa));

  const x = (i) => P.l + (i / Math.max(1, data.length - 1)) * innerW;
  const y = (v) => P.t + innerH - (v / maxCa) * innerH * 0.92;
  const yCum = (v) => P.t + innerH - (v / maxCum) * innerH * 0.92;

  const linePath = data.map((d, i) => `${i ? "L" : "M"}${x(i)},${y(d.ca)}`).join(" ");
  const areaPath = linePath + ` L${x(data.length - 1)},${P.t + innerH} L${x(0)},${P.t + innerH} Z`;
  const cumPath = data.map((d, i) => `${i ? "L" : "M"}${x(i)},${yCum(d.cumCa)}`).join(" ");

  // y-axis ticks
  const ticks = 4;
  const tickVals = Array.from({ length: ticks + 1 }, (_, i) => (maxCa / ticks) * i);

  return (
    <div className="chart-wrap" ref={wrapRef}>
      <svg viewBox={`0 0 ${W} ${H}`} style={{ width: "100%", height: H, display: "block" }}>
        {/* y grid */}
        {tickVals.map((v, i) => (
          <g key={i}>
            <line className="chart-grid" x1={P.l} x2={W - P.r} y1={y(v)} y2={y(v)} />
            <text className="chart-axis-y" x={P.l - 8} y={y(v) + 3} textAnchor="end">{fmtInt(v)}€</text>
          </g>
        ))}

        {/* area + line monthly */}
        <path className="chart-area" d={areaPath} />
        <path className="chart-line" d={linePath} />

        {/* cumulative line */}
        <path className="chart-line-cum" d={cumPath} strokeDasharray="4 3" />

        {/* dots */}
        {data.map((d, i) => (
          <circle
            key={i}
            className={`chart-dot ${hover === i ? "active" : ""}`}
            cx={x(i)} cy={y(d.ca)} r="3.5"
            onMouseEnter={() => setHover(i)}
            onMouseLeave={() => setHover(null)}
          />
        ))}

        {/* x labels */}
        {data.map((d, i) => (
          (i === 0 || i === data.length - 1 || i % Math.ceil(data.length / 6) === 0) && (
            <text key={`x${i}`} className="chart-axis-x" x={x(i)} y={H - P.b + 16} textAnchor="middle">
              {new Date(d.date + "-01").toLocaleDateString("fr-FR", { month: "short", year: "2-digit" })}
            </text>
          )
        ))}
      </svg>

      {hover !== null && (
        <div className="chart-tip" style={{
          left: `${(x(hover) / W) * 100}%`,
          top: `${(y(data[hover].ca) / H) * 100}%`,
          transform: "translate(-50%, -125%)"
        }}>
          <div className="tip-title">{new Date(data[hover].date + "-01").toLocaleDateString("fr-FR", { month: "long", year: "numeric" })}</div>
          <div className="tip-meta">CA : {fmtEUR(data[hover].ca)} € · {data[hover].count} ventes</div>
          <div className="tip-meta">Marge : {fmtEUR(data[hover].margin)} € · cumul {fmtEUR(data[hover].cumCa, { decimals: 0 })} €</div>
        </div>
      )}

      {/* Legend */}
      <div style={{ display: "flex", gap: 16, marginTop: 8, fontSize: 11.5, color: "var(--ink-3)", paddingLeft: P.l }}>
        <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
          <span style={{ width: 10, height: 2, background: "var(--accent)" }}></span> CA mensuel
        </span>
        <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
          <span style={{ width: 10, height: 2, background: "var(--ink)", borderTop: "1.5px dashed" }}></span> CA cumulé
        </span>
      </div>
    </div>
  );
};

window.Dashboard = Dashboard;
