// admin-app/dashboard.jsx — Vue d'ensemble

function DashboardPage({ data, lastFetch, refreshing, onReload }) {
  if (!data) return null;
  const invites  = data.invites  || [];
  const tables   = data.tables   || [];
  const gites    = data.gites    || [];
  const chambres = data.chambres || [];
  const covoits  = data.covoits  || [];

  // Stats RSVP
  const oui = invites.filter(i => i.rsvp_statut === "oui").length;
  const non = invites.filter(i => i.rsvp_statut === "non").length;
  const wait = invites.filter(i => !i.rsvp_statut || i.rsvp_statut === "en_attente").length;
  const total = invites.length;
  const placed = invites.filter(i => i.table_id && i.rsvp_statut === "oui").length;
  const ouiSansTable = oui - placed;
  const ouiSansGite = invites.filter(i => i.rsvp_statut === "oui" && !i.gite_id).length;

  // Côté
  const cotE = invites.filter(i => (i.cote || "").toLowerCase().startsWith("e")).length;
  const cotA = invites.filter(i => (i.cote || "").toLowerCase().startsWith("a")).length;

  // Régimes
  const regimes = invites.filter(i => i.rsvp_statut === "oui" && i.regime && i.regime !== "omni");
  const allergies = invites.filter(i => i.rsvp_statut === "oui" && i.allergies);

  // Hébergement
  const isHors = (gid) => /^hors-/.test(String(gid || ""));
  const placedChateau = invites.filter(i => i.rsvp_statut === "oui" && i.gite_id && !isHors(i.gite_id)).length;
  const placedHors    = invites.filter(i => i.rsvp_statut === "oui" && isHors(i.gite_id)).length;
  const reservedSeats = chambres.filter(c => c.reserve).reduce((s, c) => s + (Number(c.capacite) || 0), 0);
  const totalCapaChateau = chambres.length > 0
    ? chambres.reduce((s, c) => s + (Number(c.capacite) || 0), 0) - reservedSeats
    : gites.reduce((s, g) => s + (Number(g.lits) || 0), 0);
  const gitesOccupes = gites.filter(g => invites.some(i => i.rsvp_statut === "oui" && i.gite_id === g.id)).length;

  // Récents
  const recent = [...invites]
    .filter(i => i.rsvp_at)
    .sort((a, b) => new Date(b.rsvp_at) - new Date(a.rsvp_at))
    .slice(0, 5);

  // À faire
  const todos = [];
  if (ouiSansTable > 0) todos.push(`${ouiSansTable} invité${ouiSansTable > 1 ? "s" : ""} confirmé${ouiSansTable > 1 ? "s" : ""} sans table`);
  if (ouiSansGite > 0) todos.push(`${ouiSansGite} invité${ouiSansGite > 1 ? "s" : ""} à distribuer dans les gîtes`);
  if (regimes.length > 0) todos.push(`${regimes.length} régime${regimes.length > 1 ? "s" : ""} spécia${regimes.length > 1 ? "ux" : "l"} à transmettre au traiteur`);
  if (allergies.length > 0) todos.push(`${allergies.length} allergie${allergies.length > 1 ? "s" : ""} à valider avec le traiteur`);
  if (wait > 0) todos.push(`${wait} RSVP en attente — à relancer`);
  if (!todos.length) todos.push("Tout est en ordre 🎉");

  return (
    <AdPage
      eyebrow="Vue d'ensemble"
      title="Tableau de bord"
      actions={
        <button className="btn sm" onClick={onReload} disabled={refreshing}>
          {refreshing ? <AdSpinner size={11}/> : "↻"} Recharger
        </button>
      }
    >
      {/* Bandeau de statut */}
      <div style={{ fontFamily: AD.italic, fontStyle: "italic", fontSize: 14, color: AD.inkSoft, marginBottom: 18 }}>
        Dernière synchro {lastFetch ? lastFetch.toLocaleTimeString("fr-FR", { hour: "2-digit", minute: "2-digit", second: "2-digit" }) : "—"} ·
        {" "}{daysUntil("2027-08-21")} jours avant le mariage
      </div>

      {/* 4 KPI cards */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 12, marginBottom: 16 }}>
        <DashKpi value={total} label="Invités" sub={`${cotE} côté E · ${cotA} côté A`}/>
        <DashKpi value={oui + non} label="Ont répondu" sub={`${oui} oui · ${non} non`}/>
        <DashKpi value={wait} label="En attente" sub="à relancer" tone={wait > 0 ? "alert" : undefined}/>
        <DashKpi value={placed} label="Placés à table" sub={`${ouiSansTable} sans table`}/>
        <DashKpi value={placedChateau} label="Au château" sub={`${ouiSansGite} sans logement · ${placedHors} hors ch.`}/>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
        {/* À faire */}
        <AdCard accent={AD.rouge}>
          <div className="eyebrow" style={{ marginBottom: 10 }}>★ À faire</div>
          <ul style={{ margin: 0, padding: "0 0 0 18px", fontSize: 13.5, lineHeight: 1.6 }}>
            {todos.map((t, i) => (
              <li key={i} style={{ fontFamily: AD.italic, fontStyle: "italic", color: AD.ink }}>{t}</li>
            ))}
          </ul>
        </AdCard>

        {/* Activité récente */}
        <AdCard accent={AD.or}>
          <div className="eyebrow" style={{ marginBottom: 10 }}>★ Récent</div>
          {recent.length === 0 ? (
            <div style={{ fontFamily: AD.italic, fontStyle: "italic", color: AD.inkMute, fontSize: 13 }}>
              Aucune réponse pour l'instant.
            </div>
          ) : (
            <ul style={{ margin: 0, padding: 0, listStyle: "none" }}>
              {recent.map((inv, i) => (
                <li key={inv.id} style={{ padding: "6px 0", borderBottom: i < recent.length - 1 ? `1px solid ${AD.ruleSoft}` : "none", fontSize: 13 }}>
                  <strong style={{ fontFamily: AD.display, fontWeight: 700 }}>{inv.prenom} {inv.nom || ""}</strong>
                  {" "}a répondu{" "}
                  {inv.rsvp_statut === "oui" ? <AdPill color="sage" small>Oui</AdPill> : <AdPill color="rouge" small>Non</AdPill>}
                  {" "}
                  <span style={{ fontFamily: AD.mono, fontSize: 10, color: AD.inkMute }}>· {timeAgo(inv.rsvp_at)}</span>
                </li>
              ))}
            </ul>
          )}
        </AdCard>
      </div>

      {/* Compteurs détaillés */}
      <div style={{ marginTop: 24, padding: "16px 20px", background: AD.white, border: `1px solid ${AD.ruleSoft}` }}>
        <div className="eyebrow" style={{ marginBottom: 12 }}>★ Compteurs</div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 16, fontSize: 13 }}>
          <DashCounter label="Tables prêtes" value={tables.length} sub={`${invites.filter(i => i.table_id).length} placés / ${oui} oui`}/>
          <DashCounter label="Gîtes" value={gites.length} sub={`${invites.filter(i => i.gite_id).length} couchages occupés`}/>
          <DashCounter label="Régimes spé." value={regimes.length}/>
          <DashCounter label="Covoiturages" value={covoits.length} sub={`${invites.filter(i => i.covoit_id).length} passagers`}/>
        </div>
      </div>
    </AdPage>
  );
}

function DashKpi({ value, label, sub, tone }) {
  const alert = tone === "alert";
  return (
    <div style={{
      padding: 14,
      background: alert ? AD.rougePale : AD.white,
      borderLeft: `3px solid ${alert ? AD.rouge : AD.or}`,
      border: `1px solid ${AD.ruleSoft}`, borderLeftWidth: 3,
    }}>
      <div className="display-bold" style={{ fontSize: 32, color: alert ? AD.rougeDeep : AD.ink, lineHeight: 1 }}>
        {value}
      </div>
      <div className="eyebrow" style={{ marginTop: 6, color: alert ? AD.rougeDeep : AD.orDeep }}>{label}</div>
      {sub && <div style={{ fontFamily: AD.italic, fontStyle: "italic", fontSize: 11, color: AD.inkSoft, marginTop: 4 }}>{sub}</div>}
    </div>
  );
}

// ─── Jauge de contrôle : ratio X/Y avec barre de progression ──────────
function ControlGauge({ label, value, total, sub, tone }) {
  const tones = {
    ok:      { bar: AD.sage,    label: AD.inkSoft },
    warn:    { bar: AD.or,      label: AD.orDeep },
    alert:   { bar: AD.rouge,   label: AD.rougeDeep },
    info:    { bar: AD.ink,     label: AD.inkSoft },
    neutral: { bar: AD.inkMute, label: AD.inkSoft },
  };
  const t = tones[tone] || tones.ok;
  const ratio = total > 0 ? Math.min(1, value / total) : 0;
  const pct = Math.round(ratio * 100);
  return (
    <div style={{ minWidth: 0 }}>
      <div style={{ display: "flex", alignItems: "baseline", gap: 6 }}>
        <span className="display-bold" style={{ fontSize: 28, lineHeight: 1, color: AD.ink }}>{value}</span>
        <span style={{ fontFamily: AD.mono, fontSize: 13, color: AD.inkMute, lineHeight: 1 }}>/{total || "—"}</span>
        <span style={{ marginLeft: "auto", fontFamily: AD.mono, fontSize: 9, color: t.label, letterSpacing: 1 }}>{pct}%</span>
      </div>
      <div style={{ fontFamily: AD.mono, fontSize: 9, letterSpacing: 1.5, color: AD.inkSoft, textTransform: "uppercase", marginTop: 6, fontWeight: 600 }}>{label}</div>
      <div style={{ marginTop: 6, height: 4, background: AD.ruleSoft, position: "relative", overflow: "hidden" }}>
        <div style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: `${pct}%`, background: t.bar, transition: "width .3s ease-out" }}/>
      </div>
      {sub && <div style={{ fontFamily: AD.italic, fontStyle: "italic", fontSize: 11, color: AD.inkMute, marginTop: 5, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{sub}</div>}
    </div>
  );
}

function DashCounter({ label, value, sub }) {
  return (
    <div>
      <div className="display-bold" style={{ fontSize: 20, color: AD.ink, lineHeight: 1 }}>{value}</div>
      <div style={{ fontFamily: AD.mono, fontSize: 9, letterSpacing: 1, color: AD.inkSoft, textTransform: "uppercase", marginTop: 4 }}>{label}</div>
      {sub && <div style={{ fontFamily: AD.italic, fontStyle: "italic", fontSize: 11, color: AD.inkMute, marginTop: 2 }}>{sub}</div>}
    </div>
  );
}

// Helpers temps
function daysUntil(isoDate) {
  const d = (new Date(isoDate) - Date.now()) / 86400000;
  return Math.max(0, Math.floor(d));
}

function timeAgo(iso) {
  if (!iso) return "—";
  const ms = Date.now() - new Date(iso).getTime();
  const min = Math.floor(ms / 60000);
  if (min < 1) return "à l'instant";
  if (min < 60) return `il y a ${min} min`;
  const h = Math.floor(min / 60);
  if (h < 24) return `il y a ${h} h`;
  const d = Math.floor(h / 24);
  return `il y a ${d} j`;
}

Object.assign(window, { DashboardPage });
