// view-admin.jsx — briques de la vue Admin KODAMA (tableau par print, liens magiques).
// La page Admin elle-même (liste de jeux + fiche) vit dans view-admin-game.jsx.

const STATUT_OPTIONS = ["Prod Planifiée", "Validation MPC", "MPC validé", "Modifications des fichiers", "En production", "Transport en Cours", "🧾 Finaliser facturation", "Terminé"];

// ——— Détail d'un print : table partenaires éditable ———
function VideoCell({ prod, partner, update, push, readOnly }) {
  const [editing, setEditing] = React.useState(false);
  const [draft, setDraft] = React.useState("");
  if (readOnly) {
    return prod.mpcVideoUrl
      ? <ExtLink href={prod.mpcVideoUrl} style={{ fontSize: 12 }}>↗ Vidéo</ExtLink>
      : <span style={{ color: K.sub, fontSize: 12 }}>—</span>;
  }
  const save = () => {
    const v = draft.trim() ? extUrl(draft.trim()) : "";
    update((d) => {
      d.productions.find((x) => x.id === prod.id).mpcVideoUrl = v;
      d.log.unshift({ ts: nowStamp(), actor: "KODAMA (admin)", action: "Lien vidéo MPC mis à jour", detail: `${prod.gameLabel} → ${partner.name.replace(/ - .*$/, "")}` });
    });
    setEditing(false);
    push("Lien vidéo enregistré dans Airtable — visible par ce partenaire.");
  };
  if (editing) return (
    <input autoFocus className="k-input" value={draft} placeholder="https://drive.google.com/…"
      style={{ width: 150, padding: "4px 8px", fontSize: 11.5, borderRadius: 7, fontFamily: K.mono }}
      onChange={(e) => setDraft(e.target.value)} onBlur={save}
      onKeyDown={(e) => { if (e.key === "Enter") save(); if (e.key === "Escape") setEditing(false); }} />
  );
  if (prod.mpcVideoUrl) return (
    <span style={{ display: "inline-flex", gap: 8, alignItems: "center" }}>
      <ExtLink href={prod.mpcVideoUrl} style={{ fontSize: 12 }}>↗ Vidéo</ExtLink>
      <button title="Modifier le lien" onClick={() => { setDraft(prod.mpcVideoUrl); setEditing(true); }} style={{ background: "none", border: "none", cursor: "pointer", color: K.sub, fontSize: 12, padding: 0 }}>✎</button>
    </span>
  );
  const required = needsVideoLink(prod);
  return (
    <button onClick={() => { setDraft(""); setEditing(true); }} title={required ? "La validation de ce partenaire exige une vidéo — le lien est à renseigner." : ""}
      style={{ background: "none", border: "none", borderBottom: `1.5px dashed ${required ? STATE_COLORS.waiting : K.line}`, cursor: "text", padding: "2px 1px", fontSize: 12, color: required ? K.amber : K.sub, fontWeight: required ? 700 : 400, fontFamily: K.font }}>{required ? "⚠ + lien Drive requis" : "+ lien Drive"}</button>
  );
}

// ——— Tracking MPC éditable depuis l'admin (écrit dans Airtable « MPC Tracking Number ») ———
function TrackingCell({ prod, partner, update, push, readOnly }) {
  const [editing, setEditing] = React.useState(false);
  const [draft, setDraft] = React.useState("");
  if (readOnly) {
    return prod.mpcTracking
      ? <span className="k-mono" style={{ fontSize: 11.5 }}>{prod.mpcTracking}</span>
      : <span style={{ color: K.sub, fontSize: 12 }}>—</span>;
  }
  const save = () => {
    const v = draft.trim();
    if (v !== (prod.mpcTracking || "")) {
      update((d) => {
        const p = d.productions.find((x) => x.id === prod.id);
        p.mpcTracking = v;
        p.mpcTrackingOn = v ? todayIso() : null;
        d.log.unshift({ ts: nowStamp(), actor: "KODAMA (admin)", action: v ? "Tracking MPC mis à jour" : "Tracking MPC retiré", detail: `${prod.gameLabel} → ${partner.name.replace(/ - .*$/, "")}${v ? " : " + v : ""}` });
      });
      push(v ? "Tracking enregistré dans Airtable — visible par ce partenaire." : "Tracking retiré.");
    }
    setEditing(false);
  };
  if (editing) return (
    <input autoFocus className="k-input" value={draft} placeholder="SF…"
      style={{ width: 130, padding: "4px 8px", fontSize: 11.5, borderRadius: 7, fontFamily: K.mono }}
      onChange={(e) => setDraft(e.target.value)} onBlur={save}
      onKeyDown={(e) => { if (e.key === "Enter") save(); if (e.key === "Escape") setEditing(false); }} />
  );
  if (prod.mpcTracking) return (
    <span style={{ display: "inline-flex", gap: 7, alignItems: "center" }}>
      <span className="k-mono" style={{ fontSize: 11.5 }}>{prod.mpcTracking}</span>
      <button title="Modifier le tracking" onClick={() => { setDraft(prod.mpcTracking); setEditing(true); }} style={{ background: "none", border: "none", cursor: "pointer", color: K.sub, fontSize: 12, padding: 0 }}>✎</button>
    </span>
  );
  return (
    <button onClick={() => { setDraft(""); setEditing(true); }}
      style={{ background: "none", border: "none", borderBottom: `1.5px dashed ${K.line}`, cursor: "text", padding: "2px 1px", fontSize: 12, color: K.sub, fontFamily: K.font }}>+ n° de tracking</button>
  );
}

// ——— Résolution d'une demande de modifs : fichiers corrigés → re-validation MPC ———
function ResolveChangesBox({ prod, partner, update, push }) {
  const [note, setNote] = React.useState("");
  const resolve = () => {
    update((d) => {
      const p = d.productions.find((x) => x.id === prod.id);
      p.prevComment = p.comment;
      p.comment = "";
      p.fixNote = note.trim();
      p.fixedOn = todayIso();
      p.statut = "Validation MPC";
      d.log.unshift({ ts: nowStamp(), actor: "KODAMA (admin)", action: "Fichiers corrigés — re-validation demandée", detail: `${prod.gameLabel} → ${partner.name.replace(/ - .*$/, "")}` });
    });
    push("Statut repassé en « Validation MPC » — le partenaire est invité à re-valider.");
  };
  return (
    <div style={{ marginTop: 10, paddingTop: 10, borderTop: `1px dashed ${K.red}40`, display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
      <input className="k-input" value={note} onChange={(e) => setNote(e.target.value)} placeholder="Optionnel : ce qui a été corrigé — visible par le partenaire…" style={{ flex: 1, minWidth: 220, padding: "6px 10px", fontSize: 12.5, borderRadius: 8 }} />
      <button className="k-btn k-btn-primary k-btn-sm" onClick={resolve} style={{ whiteSpace: "nowrap" }}>✓ Fichiers corrigés → redemander la validation MPC</button>
    </div>
  );
}

function AdminProdRow({ prod, partner, update, push, readOnly }) {
  const [open, setOpen] = React.useState(false);
  const cell = { padding: "10px 9px", borderTop: `1px solid ${K.line}`, fontSize: 12.5, verticalAlign: "top" };
  const st = STATUS[prod.statut] || { en: prod.statut, fg: K.gray, bg: K.grayBg };
  const options = STATUT_OPTIONS.includes(prod.statut) ? STATUT_OPTIONS : [prod.statut, ...STATUT_OPTIONS];
  const hasChanges = prod.statut === "Modifications des fichiers" && !!prod.comment;
  return (
    <React.Fragment>
    <tr>
      <td style={{ ...cell, fontWeight: 700, minWidth: 110 }}>
        {readOnly ? (
          <button onClick={() => setOpen(!open)} style={{ background: "none", border: "none", cursor: "pointer", fontSize: 12.5, fontFamily: K.font, fontWeight: 700, color: K.ink, display: "flex", gap: 7, alignItems: "center", padding: 0 }}>
            <span style={{ display: "inline-block", transform: open ? "rotate(90deg)" : "none", transition: "transform .15s", color: K.sub }}>▸</span>
            {partner.flag} {partner.name.replace(/ - .*$/, "")}
          </button>
        ) : <span>{partner.flag} {partner.name.replace(/ - .*$/, "")}</span>}
        <div style={{ marginTop: 3 }}>
          {readOnly ? (
            prod.madeIn ? <span style={{ fontSize: 10.5, fontWeight: 600, color: K.sub, border: `1px solid ${K.line}`, borderRadius: 99, padding: "1px 6px" }}>Made in {prod.madeIn}</span> : null
          ) : (
          <select value={prod.madeIn || ""} title="Made in" onChange={(e) => {
            const v = e.target.value || null;
            update((d) => {
              d.productions.find((x) => x.id === prod.id).madeIn = v;
              d.log.unshift({ ts: nowStamp(), actor: "KODAMA (admin)", action: "Made in modifié", detail: `${prod.gameLabel} → ${partner.name.replace(/ - .*$/, "")}` });
            });
            push("Modification enregistrée dans Airtable.");
          }} style={{ fontFamily: K.font, fontSize: 10.5, fontWeight: 600, color: K.sub, background: "transparent", border: `1px solid ${K.line}`, borderRadius: 99, padding: "1px 6px", cursor: "pointer" }}>
            <option value="">Made in ?</option>
            {MADE_IN_OPTIONS.map((m) => <option key={m} value={m}>Made in {m}</option>)}
          </select>
          )}
        </div>
      </td>
      <td style={{ ...cell, textAlign: "right", fontFamily: K.mono }}>{prod.qty.toLocaleString("fr-FR")}</td>
      <td style={{ ...cell, color: prod.validation ? K.sub : K.amber, fontWeight: prod.validation ? 400 : 600 }}>
        {valLabel(prod.validation)}
        <div style={{ fontSize: 11, marginTop: 2, color: prod.incoterm ? K.sub : K.amber, fontWeight: prod.incoterm ? 600 : 700 }}>PL : {prod.incoterm || "⚠ à choisir"}</div>
      </td>
      <td style={cell}>
        {readOnly ? (
          <span style={{ display: "inline-block", fontSize: 12, fontWeight: 700, color: st.fg, background: st.bg, borderRadius: 99, padding: "4px 12px" }}>{prod.statut}</span>
        ) : (
        <select value={prod.statut} onChange={(e) => {
          const v = e.target.value;
          update((d) => {
            d.productions.find((x) => x.id === prod.id).statut = v;
            d.log.unshift({ ts: nowStamp(), actor: "KODAMA (admin)", action: "Statut modifié", detail: `${prod.gameLabel} → ${partner.name.replace(/ - .*$/, "")} : ${v}` });
          });
          push("Statut écrit dans Airtable.");
        }} style={{ fontFamily: K.font, fontSize: 12, fontWeight: 700, color: st.fg, background: st.bg, border: "none", borderRadius: 99, padding: "4px 10px", cursor: "pointer", maxWidth: 230 }}>
          {options.map((s) => <option key={s} value={s} style={{ color: K.ink, background: "#FFF" }}>{s}</option>)}
        </select>
        )}
      </td>
      <td style={cell}>
        {prod.mpcOk ? <span style={{ color: K.green, fontWeight: 600 }}>✓ {prod.mpcBy} · {fmtDate(prod.mpcOn)}</span> :
        hasChanges ? <span style={{ color: K.red, fontWeight: 700 }}>✎ Modifs demandées ↓</span> :
        prod.comment ? <span title={prod.comment} style={{ color: K.red, fontWeight: 600 }}>⚠ “{prod.comment.slice(0, 44)}{prod.comment.length > 44 ? "…" : ""}”</span> :
        <span style={{ color: K.amber, fontWeight: 600 }}>⏳ En attente{prod.fixedOn && prod.prevComment ? <span style={{ display: "block", fontSize: 11, color: K.sub, fontWeight: 400 }}>re-validation demandée le {fmtDate(prod.fixedOn)}</span> : null}</span>}
      </td>
      <td style={{ ...cell, whiteSpace: "nowrap" }}><TrackingCell prod={prod} partner={partner} update={update} push={push} readOnly={readOnly} /></td>
      <td style={{ ...cell, whiteSpace: "nowrap" }}>
        {prod.validation && !prod.validation.includes("Vidéo") ?
        <span style={{ color: K.sub }}>n/a</span> :
        <VideoCell prod={prod} partner={partner} update={update} push={push} readOnly={readOnly} />}
      </td>
    </tr>
    {readOnly && open &&
    <tr>
        <td colSpan={7} style={{ background: "#FBFAF8", borderTop: `1px solid ${K.line}`, padding: "16px 20px 20px" }}>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 18 }}>
            <div>
              <div className="k-label" style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>Consignee &amp; Notify {partner.consignee && <CopyBtn text={partner.consignee} />}</div>
              <pre className="k-mono" style={{ margin: "8px 0 14px", fontSize: 12, whiteSpace: "pre-wrap", background: "#FFF", border: `1px solid ${K.line}`, borderRadius: 8, padding: "10px 12px", color: partner.consignee ? K.ink : K.red }}>{partner.consignee || "✕ Pas encore renseigné par le partenaire"}</pre>
              <div className="k-label" style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>Adresse échantillons pré-prod {partner.preprod && <CopyBtn text={partner.preprod} />}</div>
              <pre className="k-mono" style={{ margin: "8px 0 0", fontSize: 12, whiteSpace: "pre-wrap", background: "#FFF", border: `1px solid ${K.line}`, borderRadius: 8, padding: "10px 12px" }}>{partner.preprod || "Pas encore renseignée"}</pre>
            </div>
            <div>
              <div className="k-label" style={{ marginBottom: 8 }}>Documents</div>
              {prod.files && prod.files.length > 0 ? (
                <div style={{ display: "flex", flexDirection: "column", gap: 5 }}>
                  {prod.files.map((f, i) => (
                    <div key={i} style={{ fontSize: 12.5, display: "flex", gap: 8, alignItems: "baseline" }}>
                      {f.url
                        ? <ExtLink href={f.url}>↓ {f.name}</ExtLink>
                        : <span className="k-link">↓ {f.name}</span>}
                      <span style={{ color: K.sub, fontSize: 11.5 }}>{f.kind}{f.date ? " · " + fmtDate(f.date) : ""}</span>
                    </div>
                  ))}
                </div>
              ) : <div style={{ fontSize: 12.5, color: K.sub }}>Aucun document pour l'instant.</div>}
              {prod.notes ? <React.Fragment>
                <div className="k-label" style={{ margin: "14px 0 6px" }}>📄 Notes</div>
                <div style={{ fontSize: 12.5, color: K.ink, whiteSpace: "pre-wrap", background: "#FFF", border: `1px solid ${K.line}`, borderRadius: 8, padding: "10px 12px" }}>{prod.notes}</div>
              </React.Fragment> : null}
            </div>
          </div>
        </td>
      </tr>
    }
    {hasChanges &&
    <tr>
        <td colSpan={7} style={{ padding: "0 9px 12px" }}>
          <div style={{ borderRadius: 10, background: K.redBg, border: `1.5px solid ${K.red}40`, padding: "10px 14px" }}>
            <div style={{ fontSize: 11, fontWeight: 800, letterSpacing: ".05em", textTransform: "uppercase", color: K.red }}>✎ Modifications demandées par {partner.name.replace(/ - .*$/, "")} — production en pause</div>
            <p style={{ margin: "5px 0 0", fontSize: 13, fontWeight: 600, color: K.ink, whiteSpace: "pre-wrap" }}>“{prod.comment}”</p>
            <p style={{ margin: "5px 0 0", fontSize: 11.5, color: K.sub }}>{readOnly ? "Production en pause — KODAMA met les fichiers à jour avant de redemander la validation du partenaire." : "Mettez les fichiers à jour, puis cliquez ci-dessous — le statut repassera en « Validation MPC » et le partenaire sera invité à re-valider."}</p>
            {!readOnly && <ResolveChangesBox prod={prod} partner={partner} update={update} push={push} />}
          </div>
        </td>
      </tr>
    }
    </React.Fragment>);

}

function AdminPrintCard({ print, db, update, push, fixed, defaultOpen, readOnly }) {
  const [openState, setOpen] = React.useState(!!defaultOpen);
  const open = fixed ? true : openState;
  const prods = db.productions.filter((p) => p.printId === print.id).map((p) => ({ ...p, gameLabel: `${print.game} · ${print.label}` }));
  const counts = stateCounts(prods);
  const changes = prods.filter((p) => p.statut === "Modifications des fichiers");
  const waiting = prods.filter((p) => !p.mpcOk && p.statut !== "Modifications des fichiers" && ["Validation MPC", "Prod Planifiée"].includes(p.statut));
  const videoMissing = prods.filter(needsVideoLink);
  const allDone = prods.length > 0 && prods.every((p) => p.statut === "Terminé");
  const pname = (p) => db.partners.find((x) => x.id === p.partnerId).name.replace(/ - .*$/, "");
  return (
    <div className="k-card" style={{ marginTop: 10, overflow: "hidden" }}>
      <button onClick={() => { if (!fixed) setOpen(!openState); }} style={{ all: "unset", boxSizing: "border-box", display: "block", width: "100%", padding: "13px 18px 14px", cursor: fixed ? "default" : "pointer" }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 10, flexWrap: "wrap" }}>
          <div className="k-round" style={{ fontSize: 16.5, fontWeight: 700 }}>
            {!fixed && <span style={{ display: "inline-block", transform: open ? "rotate(90deg)" : "none", transition: "transform .15s", color: K.sub, marginRight: 8 }}>▸</span>}
            {fixed ? `${print.game} · ${print.label}` : print.label} <span style={{ color: K.sub, fontWeight: 500, fontSize: 13.5 }}>· {prods.length} partenaire{prods.length > 1 ? "s" : ""}</span>
            {allDone && <span style={{ color: K.sub, fontWeight: 600, fontSize: 12, marginLeft: 8 }}>✓ terminé</span>}
          </div>
          <span style={{ display: "inline-flex", gap: 14, alignItems: "baseline" }}>
            <StateCounters counts={counts} labels={{ ok: "validés", waiting: "en attente", changes: "modifs", done: "terminés" }} />
            <span className="k-mono" style={{ fontSize: 12, color: K.sub }}>{prods.reduce((s, p) => s + p.qty, 0).toLocaleString("fr-FR")} ex.</span>
          </span>
        </div>
        <StateBar counts={counts} style={{ marginTop: 9 }} />
        <div style={{ marginTop: 8, fontSize: 12.5, display: "flex", flexDirection: "column", gap: 2 }}>
          {waiting.length > 0 && <span style={{ color: K.amber, fontWeight: 600 }}>⏳ En attente : {waiting.map(pname).join(", ")}</span>}
          {changes.length > 0 && <span style={{ color: K.red, fontWeight: 600 }}>✎ Modifications demandées : {changes.map(pname).join(", ")}</span>}
          {videoMissing.length > 0 && <span style={{ color: K.amber, fontWeight: 600 }}>🎬 Lien vidéo MPC à renseigner : {videoMissing.map(pname).join(", ")}</span>}
          {!allDone && waiting.length === 0 && changes.length === 0 && videoMissing.length === 0 && <span style={{ color: K.green, fontWeight: 600 }}>✓ Tous les partenaires ont validé.</span>}
        </div>
      </button>
      {open &&
      <div style={{ borderTop: `1px solid ${K.line}` }}>
          <div style={{ overflowX: "auto" }}>
          <table style={{ width: "100%", borderCollapse: "collapse" }}>
            <thead>
              <tr>{["Partenaire", "Qté", "Validation", "Statut Prod'", "MPC", "Tracking", "Vidéo MPC"].map((h, i) =>
              <th key={h} className="k-label" style={{ textAlign: i === 1 ? "right" : "left", padding: "10px 9px", fontSize: 10.5 }}>{h}</th>
              )}</tr>
            </thead>
            <tbody>
              {prods.map((p) => <AdminProdRow key={p.id} prod={p} partner={db.partners.find((x) => x.id === p.partnerId)} update={update} push={push} readOnly={readOnly} />)}
            </tbody>
          </table>
          </div>
          <div style={{ padding: "10px 20px 14px", fontSize: 12.5, color: K.sub, display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap", borderTop: `1px solid ${K.line}` }}>
            <span className="k-label" style={{ fontSize: 10.5 }}>Localized files + Carton Marks</span>
            {print.cartonMarksUrl ? <React.Fragment>
              <ExtLink href={print.cartonMarksUrl} style={{ fontSize: 12.5 }}>↗ Drive partagé</ExtLink>
              <CopyBtn text={print.cartonMarksUrl} label="Copier" />
            </React.Fragment> : <span style={{ color: K.amber, fontWeight: 600 }}>Pas encore de lien — l'usine peut l'ajouter depuis sa vue.</span>}
          </div>
        </div>
      }
    </div>);

}

// ((La carte Jeu en accordéon a été remplacée par le sélecteur GamePrintPicker, partagé avec la vue Usine.))

function TokenRow({ partner, db, update, push, readOnly }) {
  const link = `https://portal.kodama.games/p/${partner.token}`;
  const stale = monthsAgo(partner.confirmedOn) > 6;
  return (
    <tr>
      <td style={{ padding: "10px 14px", borderTop: `1px solid ${K.line}`, fontWeight: 700, fontSize: 13, whiteSpace: "nowrap" }}>{partner.flag} {partner.name.replace(/ - .*$/, "")}</td>
      <td style={{ padding: "10px 14px", borderTop: `1px solid ${K.line}` }}>
        <a className="k-mono k-link" href={link} target="_blank" rel="noopener noreferrer" style={{ fontSize: 11.5 }}>{link}</a>
      </td>
      <td style={{ padding: "10px 14px", borderTop: `1px solid ${K.line}`, fontSize: 12, color: stale ? K.amber : K.sub, whiteSpace: "nowrap" }}>
        {partner.confirmedOn ? `Infos confirmées ${fmtDate(partner.confirmedOn)}` : <span style={{ color: K.red, fontWeight: 600 }}>Jamais confirmées</span>}
      </td>
      <td style={{ padding: "10px 14px", borderTop: `1px solid ${K.line}`, whiteSpace: "nowrap", textAlign: "right" }}>
        <span style={{ display: "inline-flex", gap: 6 }}>
          <CopyBtn text={link} label="Copier le lien" />
          {!readOnly && <button className="k-copy" onClick={() => {
            update((d) => {
              const p = d.partners.find((x) => x.id === partner.id);
              p.token = "pt_" + partner.id + "_" + Math.random().toString(36).slice(2, 7);
              d.log.unshift({ ts: nowStamp(), actor: "KODAMA (admin)", action: "Token régénéré", detail: partner.name });
            });
            push("Nouveau lien généré — l'ancien lien est invalidé.");
          }} style={{ background: "#FFF", border: `1.5px solid ${K.line}`, color: K.ink, borderRadius: 8, padding: "4px 10px", fontSize: 12, fontWeight: 700, cursor: "pointer", fontFamily: K.font }}>↻ Régénérer</button>}
        </span>
      </td>
    </tr>);

}

// ((L'AdminView « sélecteur en haut + print » historique a été remplacé par la fiche jeu — voir view-admin-game.jsx.))

// Page token invalide
function InvalidTokenView() {
  return (
    <div style={{ minHeight: "100vh", background: K.bg, display: "flex", alignItems: "center", justifyContent: "center", padding: 20 }}>
      <div className="k-card" style={{ maxWidth: 440, padding: "36px 38px", textAlign: "center" }}>
        <img src="assets/kodama-logo-white.png" alt="KODAMA — Playful spirit" style={{ height: 80, background: K.black, borderRadius: 14, padding: "14px 22px", boxSizing: "content-box" }} />
        <h1 className="k-round" style={{ fontSize: 24, fontWeight: 700, margin: "18px 0 8px" }}>This link isn't valid anymore</h1>
        <p style={{ color: K.sub, margin: 0 }}>Your access link may have been regenerated for security. Please ask your KODAMA contact to send you a fresh one — it only takes a minute.</p>
        <div style={{ height: 4, background: K.grad, borderRadius: 99, margin: "22px auto 0", width: 80 }}></div>
      </div>
    </div>);

}
Object.assign(window, { AdminPrintCard, TokenRow, InvalidTokenView, STATUT_OPTIONS });