// view-admin-finance.jsx — onglets « Chiffres » (facturation) et « Transport » de la fiche jeu admin.
// Miroir des champs Airtable : 🏭 Statut Facturation, N° Facturation, FAC €/$, Date de virement,
// Prix Export 🌎, CA / Bénéfice / Marge Post Prod', et la table 🚢 🚛 Transports.

const FACT_COLORS = {
  "paid": { fg: K.green, bg: K.greenBg },
  "Unpaid": { fg: K.amber, bg: K.amberBg },
  "Acompte 50%": { fg: K.blueS, bg: K.blueBg },
  "URGENT": { fg: K.red, bg: K.redBg },
  "En prod'": { fg: K.gray, bg: K.grayBg },
};
const TRANSPORT_STATUS_COLORS = {
  "Planifié": { fg: K.gray, bg: K.grayBg },
  "Transport Validé - Fournir les documents": { fg: K.amber, bg: K.amberBg },
  "Transport en cours": { fg: K.amber, bg: K.amberBg },
  "Export": { fg: K.blueS, bg: K.blueBg },
  "Done": { fg: K.green, bg: K.greenBg },
};

function pctFmt(v) {
  if (v == null || isNaN(v)) return "—";
  return Math.round(v * 100) + " %";
}
function euroFmt(n, dec) {
  if (n == null || n === "" || isNaN(n)) return "—";
  return Number(n).toLocaleString("fr-FR", { minimumFractionDigits: dec == null ? 0 : dec, maximumFractionDigits: dec == null ? 0 : dec }) + " €";
}

function setProdField(update, push, prod, partner, key, value, label) {
  update((d) => {
    const p = d.productions.find((x) => x.id === prod.id);
    if (!p) return;
    p[key] = value;
    d.log.unshift({ ts: nowStamp(), actor: "KODAMA (admin)", action: label, detail: `${prod.gameLabel} → ${partner.name.replace(/ - .*$/, "")}` });
  });
  push("Modification enregistrée dans Airtable.");
}

// Petite cellule éditable au clic (texte, montant ou date)
function EditCell({ value, display, placeholder, type, mono, width, onSave }) {
  const [editing, setEditing] = React.useState(false);
  const [draft, setDraft] = React.useState("");
  const save = () => {
    setEditing(false);
    let v = draft.trim();
    if (type === "number") { v = v === "" ? null : Number(v.replace(",", ".")); if (v !== null && isNaN(v)) return; }
    if (v !== (value == null ? (type === "number" ? null : "") : value)) onSave(v);
  };
  if (editing) return (
    <input autoFocus className="k-input" type={type === "date" ? "date" : "text"} value={draft}
      style={{ width: width || 105, padding: "3px 7px", fontSize: 11.5, borderRadius: 7, fontFamily: mono ? K.mono : K.font }}
      onChange={(e) => setDraft(e.target.value)} onBlur={save}
      onKeyDown={(e) => { if (e.key === "Enter") save(); if (e.key === "Escape") setEditing(false); }} />
  );
  const empty = value == null || value === "";
  return (
    <button onClick={() => { setDraft(value == null ? "" : String(type === "date" ? String(value).slice(0, 10) : value)); setEditing(true); }}
      title="Cliquer pour modifier"
      style={{ background: "none", border: "none", borderBottom: empty ? `1.5px dashed ${K.line}` : "none", cursor: "text", padding: "1px 1px",
        fontSize: empty ? 11.5 : 12, color: empty ? K.sub : K.ink, fontFamily: mono ? K.mono : K.font, fontWeight: empty ? 400 : 600, textAlign: "left" }}>
      {empty ? (placeholder || "+ ajouter") : (display != null ? display : value)}
    </button>
  );
}

function FactStatutSelect({ prod, partner, update, push }) {
  const v = prod.factStatut;
  const c = FACT_COLORS[v] || { fg: K.gray, bg: K.grayBg };
  const options = v && !FACT_STATUTS.includes(v) ? [v, ...FACT_STATUTS] : FACT_STATUTS;
  return (
    <select value={v || ""} onChange={(e) => setProdField(update, push, prod, partner, "factStatut", e.target.value || null, "Statut facturation modifié")}
      style={{ fontFamily: K.font, fontSize: 11.5, fontWeight: 700, color: v ? c.fg : K.sub, background: v ? c.bg : "#FFF",
        border: v ? "none" : `1.5px solid ${K.line}`, borderRadius: 99, padding: "3px 9px", cursor: "pointer", maxWidth: 190 }}>
      <option value="">—</option>
      {options.map((s) => <option key={s} value={s} style={{ color: K.ink, background: "#FFF" }}>{s}</option>)}
    </select>
  );
}

// ——— Tableau facturation d'un print ———
function FinancePrintCard({ print, db, update, push }) {
  const prods = db.productions.filter((p) => p.printId === print.id).map((p) => ({ ...p, gameLabel: `${print.game} · ${print.label}` }));
  if (prods.length === 0) return null;
  const cell = { padding: "9px 8px", borderTop: `1px solid ${K.line}`, fontSize: 12, verticalAlign: "top" };
  const head = { textAlign: "left", padding: "9px 8px", fontSize: 10.5, fontWeight: 800, letterSpacing: ".04em", textTransform: "uppercase", color: K.sub, whiteSpace: "nowrap" };
  const caTotal = prods.reduce((s, p) => s + (p.caPost || 0), 0);
  const benefTotal = prods.reduce((s, p) => s + (p.benefPost || 0), 0);
  return (
    <div className="k-card" style={{ marginTop: 10, overflow: "hidden" }}>
      <div style={{ padding: "12px 18px 10px", display: "flex", gap: 14, alignItems: "baseline", flexWrap: "wrap" }}>
        <div className="k-round" style={{ fontSize: 16, fontWeight: 700 }}>{print.label}</div>
        <span style={{ fontSize: 12, color: K.sub }}>
          Prix export {prods[0] && prods[0].prixExport != null ? euroFmt(prods[0].prixExport, 2) : "—"} · Prix de prod {prods[0] && prods[0].prixProd != null ? euroFmt(prods[0].prixProd, 2) : "—"}
        </span>
        <span style={{ marginLeft: "auto", fontSize: 12.5, fontWeight: 700 }}>
          CA {euroFmt(caTotal)} <span style={{ color: K.green }}>· Bénéfice {euroFmt(benefTotal)}</span>
        </span>
      </div>
      <div style={{ overflowX: "auto" }}>
        <table style={{ width: "100%", borderCollapse: "collapse", minWidth: 830 }}>
          <thead><tr>
            <th style={head}>Partenaire</th>
            <th style={{ ...head, textAlign: "right" }}>Qté</th>
            <th style={{ ...head, textAlign: "right" }}>Palettes $</th>
            <th style={{ ...head, textAlign: "right" }}>Prix exp.</th>
            <th style={{ ...head, textAlign: "right" }}>CA Post Prod'</th>
            <th style={{ ...head, textAlign: "right" }}>Bénéfice</th>
            <th style={{ ...head, textAlign: "right" }}>Marge</th>
            <th style={head}>Facturation</th>
            <th style={head}>Facture</th>
          </tr></thead>
          <tbody>
            {prods.map((p) => {
              const partner = db.partners.find((x) => x.id === p.partnerId) || { name: "?", flag: "" };
              return (
                <tr key={p.id}>
                  <td style={{ ...cell, fontWeight: 700, whiteSpace: "nowrap" }}>{partner.flag} {partner.name.replace(/ - .*$/, "")}</td>
                  <td style={{ ...cell, textAlign: "right", fontFamily: K.mono }}>{(p.qty || 0).toLocaleString("fr-FR")}</td>
                  <td style={{ ...cell, textAlign: "right", whiteSpace: "nowrap" }}>
                    {(() => {
                      if (p.wantsPallets === false) return <span style={{ color: K.sub, fontSize: 11 }}>sans palettes</span>;
                      const pal = palletInfo(p.qty, db.basicData[print.gameId]);
                      if (!pal || !pal.cost) return <span style={{ color: K.sub }}>—</span>;
                      return (
                        <div>
                          <span className="k-mono" style={{ fontWeight: 600 }}>{pal.cost.toLocaleString("fr-FR")} $</span>
                          <div style={{ fontSize: 10.5, color: K.sub }}>{Math.ceil(pal.pallets)} pal × {PALLET_COST_USD} $</div>
                        </div>
                      );
                    })()}
                  </td>
                  <td style={{ ...cell, textAlign: "right" }}>
                    <EditCell mono={true} width={70} value={p.prixExport} display={euroFmt(p.prixExport, 2)} placeholder="—"
                      type="number" onSave={(v) => setProdField(update, push, p, partner, "prixExport", v, "Prix export modifié")} />
                  </td>
                  <td style={{ ...cell, textAlign: "right", fontFamily: K.mono, fontWeight: 600 }}>{euroFmt(p.caPost)}</td>
                  <td style={{ ...cell, textAlign: "right", fontFamily: K.mono, color: p.benefPost != null && p.benefPost < 0 ? K.red : K.green, fontWeight: 600 }}>{euroFmt(p.benefPost)}</td>
                  <td style={{ ...cell, textAlign: "right", fontFamily: K.mono }}>
                    {pctFmt(p.margePost)}
                    {p.margeReelle != null && p.margeReelle !== 0 ? <div style={{ fontSize: 10.5, color: K.sub }}>réelle {pctFmt(p.margeReelle)}</div> : null}
                  </td>
                  <td style={cell}><FactStatutSelect prod={p} partner={partner} update={update} push={push} /></td>
                  <td style={{ ...cell, minWidth: 150 }}>
                    <div style={{ display: "flex", flexDirection: "column", gap: 3 }}>
                      <EditCell mono={true} width={140} value={p.numFact} placeholder="+ n° de facture"
                        onSave={(v) => setProdField(update, push, p, partner, "numFact", v, "N° de facture modifié")} />
                      <div style={{ display: "flex", gap: 8, alignItems: "baseline", flexWrap: "wrap" }}>
                        <EditCell mono={true} width={80} value={p.facEuros} display={p.facEuros != null ? euroFmt(p.facEuros, 2) : null} placeholder="+ FAC €"
                          type="number" onSave={(v) => setProdField(update, push, p, partner, "facEuros", v, "FAC € modifié")} />
                        <EditCell width={120} value={p.virement} display={p.virement ? "virement " + fmtDate(p.virement) : null} placeholder="+ virement"
                          type="date" onSave={(v) => setProdField(update, push, p, partner, "virement", v || null, "Date de virement modifiée")} />
                      </div>
                      {(p.factureFiles || []).length > 0 && (
                        <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                          {p.factureFiles.map((f, i) => <ExtLink key={i} href={f.url || "#"} style={{ fontSize: 11 }}>↓ {f.name.length > 26 ? f.name.slice(0, 24) + "…" : f.name}</ExtLink>)}
                        </div>
                      )}
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function GameFinanceSection({ game, db, update, push }) {
  const prods = db.productions.filter((p) => db.prints.some((pr) => pr.id === p.printId && pr.gameId === game.id));
  const caTotal = prods.reduce((s, p) => s + (p.caPost || 0), 0);
  const benefTotal = prods.reduce((s, p) => s + (p.benefPost || 0), 0);
  const margeMoy = caTotal > 0 ? benefTotal / caTotal : null;
  const unpaid = prods.filter((p) => p.factStatut && p.factStatut !== "paid").length;
  return (
    <div style={{ marginTop: 18 }}>
      <SectionLabel>Facturation & marges</SectionLabel>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(170px, 1fr))", gap: 10, marginTop: 10 }}>
        <BigNum label="CA Post Prod'" value={euroFmt(caTotal)} sub="toutes productions export" />
        <BigNum label="Bénéfice Post Prod'" value={euroFmt(benefTotal)} bg={K.greenBg} fg={K.green} />
        <BigNum label="Marge moyenne" value={pctFmt(margeMoy)} sub="pondérée par le CA" />
        <BigNum label="Factures à suivre" value={unpaid} sub={unpaid > 0 ? "non soldées" : "tout est payé"} fg={unpaid > 0 ? K.amber : undefined} bg={unpaid > 0 ? K.amberBg : undefined} />
      </div>
      {game.prints.map((pr) => <FinancePrintCard key={pr.id} print={pr} db={db} update={update} push={push} />)}
      <p style={{ fontSize: 11.5, color: K.sub, margin: "8px 2px 0" }}>CA, bénéfice et marge sont calculés par Airtable (formules) — le coût palettes est calculé automatiquement ({PALLET_COST_USD} $ par palette entamée) ; le prix export, le statut, le n° de facture, le montant FAC € et la date de virement s'écrivent directement dans la table Productions.</p>
    </div>
  );
}

// ——— Onglet Transport ———
function TransportCard({ tr, db, update, push }) {
  const sc = TRANSPORT_STATUS_COLORS[tr.status] || { fg: K.gray, bg: K.grayBg };
  const prods = db.productions.filter((p) => (p.transportIds || []).includes(tr.id));
  const partnerNames = prods.map((p) => {
    const pa = db.partners.find((x) => x.id === p.partnerId);
    return pa ? pa.flag + " " + pa.name.replace(/ - .*$/, "") : "?";
  });
  const setT = (key, label) => (v) => {
    update((d) => {
      const t = d.transports.find((x) => x.id === tr.id);
      if (!t) return;
      t[key] = v;
      d.log.unshift({ ts: nowStamp(), actor: "KODAMA (admin)", action: label, detail: tr.name });
    });
    push("Modification enregistrée dans Airtable.");
  };
  const field = (label, content) => (
    <div>
      <div style={{ fontSize: 10.5, fontWeight: 800, letterSpacing: ".05em", textTransform: "uppercase", color: K.sub, marginBottom: 3 }}>{label}</div>
      <div style={{ fontSize: 12.5 }}>{content}</div>
    </div>
  );
  return (
    <div className="k-card" style={{ marginTop: 10, padding: "14px 18px" }}>
      <div style={{ display: "flex", gap: 10, alignItems: "baseline", flexWrap: "wrap" }}>
        <div className="k-round" style={{ fontSize: 15.5, fontWeight: 700 }}>{(tr.type || []).join(" ")} {tr.name}</div>
        <Pill fg={sc.fg} bg={sc.bg}>{tr.status}</Pill>
        {partnerNames.length > 0 && <span style={{ fontSize: 12, color: K.sub }}>{partnerNames.join(" · ")}</span>}
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(130px, 1fr))", gap: 14, marginTop: 12 }}>
        {field("Départ", <span className="k-mono">{tr.departure ? fmtDate(tr.departure) : "—"}</span>)}
        {field("Arrivée", <span className="k-mono">{tr.arrival ? fmtDate(tr.arrival) : "—"}</span>)}
        {field("Coût", <span className="k-mono" style={{ fontWeight: 600 }}>{euroFmt(tr.cost, 2)}</span>)}
        {field("Payement",
          <select value={tr.payement || ""} onChange={(e) => setT("payement", "Payement transport modifié")(e.target.value || null)}
            style={{ fontFamily: K.font, fontSize: 11.5, fontWeight: 700,
              color: tr.payement === "Payé" ? K.green : tr.payement === "À payer" ? K.amber : K.sub,
              background: tr.payement === "Payé" ? K.greenBg : tr.payement === "À payer" ? K.amberBg : "#FFF",
              border: tr.payement ? "none" : `1.5px solid ${K.line}`, borderRadius: 99, padding: "3px 10px", cursor: "pointer" }}>
            <option value="">—</option>
            {TRANSPORT_PAYEMENT.map((s) => <option key={s} value={s} style={{ color: K.ink, background: "#FFF" }}>{s}</option>)}
          </select>)}
        {field("Ref. transporteur",
          <EditCell mono={true} width={130} value={tr.ref} placeholder="+ référence"
            onSave={(v) => setT("ref", "Ref. transporteur modifiée")(v)} />)}
      </div>
      <div style={{ marginTop: 12 }}>
        <div style={{ fontSize: 10.5, fontWeight: 800, letterSpacing: ".05em", textTransform: "uppercase", color: K.sub, marginBottom: 3 }}>Notes</div>
        <EditCell width={300} value={tr.notes} placeholder="+ note (TRAIN ?, consignes…)"
          onSave={(v) => setT("notes", "Note transport modifiée")(v)} />
      </div>
      {(tr.docs || []).length > 0 && (
        <div style={{ display: "flex", gap: 14, flexWrap: "wrap", marginTop: 12, paddingTop: 10, borderTop: `1px solid ${K.line}` }}>
          {tr.docs.map((f, i) => <ExtLink key={i} href={f.url || "#"} style={{ fontSize: 12 }}>↓ {f.name} <span style={{ color: K.sub, fontWeight: 400 }}>· {f.kind}</span></ExtLink>)}
        </div>
      )}
    </div>
  );
}

function GameTransportSection({ game, db, update, push }) {
  const prods = db.productions.filter((p) => db.prints.some((pr) => pr.id === p.printId && pr.gameId === game.id));
  const trIds = {};
  prods.forEach((p) => (p.transportIds || []).forEach((t) => { trIds[t] = true; }));
  const transports = db.transports.filter((t) => trIds[t.id]);
  const waiting = prods.filter((p) => (p.transportIds || []).length === 0 && p.statut !== "Terminé" && p.statut !== "Transport en Cours");
  return (
    <div style={{ marginTop: 4 }}>
      {transports.map((tr) => <TransportCard key={tr.id} tr={tr} db={db} update={update} push={push} />)}
      {transports.length === 0 && (
        <div className="k-card" style={{ marginTop: 12, padding: 20, color: K.sub, textAlign: "center" }}>Aucun dossier transport pour ce jeu — ils se créent dans Airtable (table 🚢 🚛 Transports) en liant la production.</div>
      )}
      {waiting.length > 0 && transports.length > 0 && (
        <p style={{ fontSize: 11.5, color: K.sub, margin: "10px 2px 0" }}>{waiting.length} production{waiting.length > 1 ? "s" : ""} de ce jeu sans dossier transport pour l'instant.</p>
      )}
    </div>
  );
}

Object.assign(window, { GameFinanceSection, GameTransportSection, FinancePrintCard, TransportCard, FACT_COLORS, TRANSPORT_STATUS_COLORS });
