// Moderation.jsx — page /moderation
//
// Liste les révisions en attente (pour modérateurs+) ou les révisions
// de l'utilisateur connecté (pour contributors). Modal d'inspection
// avec <RevisionDiff> + boutons Approuver/Rejeter (modos) ou Retirer
// (auteur).

function Moderation({ setRoute, setPlantId }) {
  const auth = window.useAuth ? window.useAuth() : { user: null, loading: false };
  const isMobile = useMobile();
  const role = auth.user?.role || null;
  const isModerator = role === "moderator" || role === "admin";

  const [revisions, setRevisions] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState(null);
  const [statusFilter, setStatusFilter] = React.useState(isModerator ? "pending" : "all");
  const [selectedId, setSelectedId] = React.useState(null);
  const [refreshKey, setRefreshKey] = React.useState(0);

  // Guard d'accès
  if (!auth.loading && !auth.user) {
    return (
      <main className="page-enter">
        <section style={{ padding: "120px 0", textAlign: "center" }}>
          <div style={{ maxWidth: 560, margin: "0 auto", padding: "0 20px" }}>
            <div className="kicker" style={{ marginBottom: 18, color: "var(--moss-deep)" }}>Accès restreint</div>
            <h1 className="h-display" style={{ fontSize: "clamp(40px, 7vw, 64px)", lineHeight: 1, margin: "0 0 24px" }}>
              Connectez-vous pour accéder à la modération.
            </h1>
            <p style={{ fontFamily: "var(--serif)", fontSize: 18, lineHeight: 1.55, color: "var(--ink-soft)", margin: "0 0 32px" }}>
              Cette page est réservée aux contributeurs invités du recueil.
            </p>
            <button className="btn" onClick={() => setRoute("home")}>Retour à l'accueil</button>
          </div>
        </section>
      </main>
    );
  }

  React.useEffect(() => {
    if (!auth.user) return;
    setLoading(true);
    const params = new URLSearchParams();
    if (statusFilter && statusFilter !== "all") params.set("status", statusFilter);
    const url = `/api/list-revisions${params.toString() ? "?" + params : ""}`;
    (window.authedFetch || fetch)(url, { cache: "no-store" })
      .then(r => r.ok ? r.json() : Promise.reject(r))
      .then(d => { setRevisions(d.revisions || []); setLoading(false); setError(null); })
      .catch(async (err) => {
        const msg = err.json ? (await err.json()).error : "Erreur de chargement";
        setError(msg);
        setLoading(false);
      });
  }, [auth.user, statusFilter, refreshKey]);

  const refresh = () => setRefreshKey(k => k + 1);

  // ── Rendu ────────────────────────────────────────────────────────────
  return (
    <main className="page-enter">
      <section style={{ padding: isMobile ? "30px 0 20px" : "60px 0 40px" }}>
        <div style={{ maxWidth: 1200, margin: "0 auto", padding: isMobile ? "0 20px" : "0 40px" }}>
          <div className="kicker" style={{ marginBottom: isMobile ? 12 : 18, color: "var(--moss-deep)" }}>
            {isModerator ? "Comité de modération" : "Mes contributions"}
          </div>
          <h1 className="h-display" style={{ fontSize: isMobile ? "clamp(38px, 9vw, 56px)" : "clamp(56px, 7vw, 88px)", lineHeight: 0.95, margin: "0 0 16px", letterSpacing: "-0.02em" }}>
            {isModerator
              ? <><span className="h-italic">Propositions</span> en attente.</>
              : <><span className="h-italic">Mes propositions</span>.</>}
          </h1>
          {!isMobile && (
            <p style={{ fontFamily: "var(--serif)", fontSize: 19, lineHeight: 1.5, color: "var(--ink-soft)", maxWidth: 720, margin: 0 }}>
              {isModerator
                ? "Examinez les contributions soumises et validez ou refusez selon la qualité botanique et l'intérêt éditorial."
                : "Suivez l'état de vos propositions de modifications et créations soumises au comité."}
            </p>
          )}
        </div>
      </section>

      {/* Filtres */}
      <section style={{ padding: isMobile ? "0 20px" : "0 40px", maxWidth: 1200, margin: "0 auto 16px" }}>
        <div style={{ display: "flex", gap: 6, flexWrap: "wrap", paddingBottom: 12, borderBottom: "1px solid var(--line-soft)" }}>
          {["pending", "approved", "rejected", "cancelled", "all"].map(s => (
            <button
              key={s}
              onClick={() => setStatusFilter(s)}
              style={{
                padding: "6px 12px",
                fontFamily: "var(--mono)",
                fontSize: 10,
                letterSpacing: ".14em",
                textTransform: "uppercase",
                background: statusFilter === s ? "var(--moss-deep)" : "transparent",
                color: statusFilter === s ? "var(--paper)" : "var(--ink-mute)",
                border: "1px solid",
                borderColor: statusFilter === s ? "var(--moss-deep)" : "var(--line)",
                cursor: "pointer",
                transition: "all 200ms var(--ease)",
              }}
            >
              {s === "all" ? "toutes" :
                s === "pending" ? "en attente" :
                s === "approved" ? "approuvées" :
                s === "rejected" ? "refusées" : "annulées"}
            </button>
          ))}
        </div>
      </section>

      {/* Liste */}
      <section style={{ padding: isMobile ? "0 20px 80px" : "0 40px 80px", maxWidth: 1200, margin: "0 auto" }}>
        {loading ? (
          <p style={{ fontFamily: "var(--serif)", fontStyle: "italic", color: "var(--ink-mute)", textAlign: "center", padding: 40 }}>
            Chargement…
          </p>
        ) : error ? (
          <div style={{ padding: 20, background: "rgba(192, 57, 43, 0.08)", borderLeft: "3px solid #c0392b", fontFamily: "var(--serif)", color: "var(--ink-soft)" }}>
            <strong>Erreur :</strong> {error}
          </div>
        ) : revisions.length === 0 ? (
          <p style={{ fontFamily: "var(--serif)", fontStyle: "italic", color: "var(--ink-mute)", textAlign: "center", padding: 40, fontSize: 18 }}>
            {statusFilter === "pending"
              ? (isModerator ? "Aucune proposition en attente. Tout est validé." : "Vous n'avez aucune proposition en attente.")
              : "Aucune révision trouvée pour ce filtre."}
          </p>
        ) : (
          <div style={{ display: "grid", gap: 12 }}>
            {revisions.map(r => (
              <RevisionCard
                key={r.id}
                revision={r}
                onClick={() => setSelectedId(r.id)}
                isModerator={isModerator}
                currentUserEmail={auth.user?.email}
              />
            ))}
          </div>
        )}
      </section>

      {/* Modal de détail */}
      {selectedId && (
        <RevisionDetailModal
          revisionId={selectedId}
          onClose={() => setSelectedId(null)}
          isModerator={isModerator}
          currentUserEmail={auth.user?.email}
          onRefresh={() => { setSelectedId(null); refresh(); }}
        />
      )}
    </main>
  );
}

// ── RevisionCard ──────────────────────────────────────────────────────

function RevisionCard({ revision, onClick, isModerator, currentUserEmail }) {
  const actionLabels = {
    create: { label: "Création", color: "#12b76a" },
    update: { label: "Édition", color: "var(--moss-deep)" },
    delete_fiche: { label: "Suppression", color: "#d92d20" },
  };
  const statusLabels = {
    pending: { label: "en attente", color: "#dc6803", bg: "#fef3c7" },
    approved: { label: "approuvée", color: "#067647", bg: "#d1fadf" },
    rejected: { label: "refusée", color: "#b42318", bg: "#fee4e2" },
    cancelled: { label: "annulée", color: "var(--ink-mute)", bg: "var(--cream)" },
  };

  const action = actionLabels[revision.action] || actionLabels.update;
  const status = statusLabels[revision.status] || statusLabels.pending;

  const initial = (revision.author_name || revision.author_email || "?")[0].toUpperCase();
  const timeAgo = formatTimeAgo(revision.created_at);
  const isOwnRevision = revision.author_email === currentUserEmail;

  return (
    <button
      onClick={onClick}
      style={{
        textAlign: "left",
        padding: "18px 22px",
        background: "var(--paper)",
        border: "1px solid var(--line)",
        borderLeft: `3px solid ${action.color}`,
        cursor: "pointer",
        fontFamily: "inherit",
        transition: "all 200ms var(--ease)",
        display: "grid",
        gridTemplateColumns: "44px 1fr auto",
        gap: 16,
        alignItems: "center",
      }}
      onMouseEnter={e => { e.currentTarget.style.background = "var(--cream)"; }}
      onMouseLeave={e => { e.currentTarget.style.background = "var(--paper)"; }}
    >
      <div style={{
        width: 44, height: 44, borderRadius: "50%",
        background: "var(--cream)",
        border: "1px solid var(--line)",
        color: "var(--moss-deep)",
        display: "grid", placeItems: "center",
        fontFamily: "var(--display)", fontSize: 18,
      }}>{initial}</div>
      <div style={{ minWidth: 0 }}>
        <div style={{ display: "flex", alignItems: "baseline", gap: 10, flexWrap: "wrap", marginBottom: 4 }}>
          <span style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: ".14em", textTransform: "uppercase", color: action.color, fontWeight: 600 }}>
            {action.label}
          </span>
          <span style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: ".14em", textTransform: "uppercase", color: status.color, background: status.bg, padding: "2px 7px" }}>
            {status.label}
          </span>
          {isOwnRevision && (
            <span style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--ink-mute)" }}>
              · votre proposition
            </span>
          )}
        </div>
        <div style={{ fontFamily: "var(--serif)", fontSize: 16, lineHeight: 1.4, color: "var(--ink)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
          {revision.summary}
        </div>
        <div style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: ".10em", color: "var(--ink-mute)", marginTop: 4 }}>
          {revision.author_email} · {timeAgo}
          {revision.reviewed_by && ` · examinée par ${revision.reviewed_by}`}
        </div>
      </div>
      <div style={{ fontFamily: "var(--mono)", fontSize: 11, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--moss-deep)" }}>
        Détail →
      </div>
    </button>
  );
}

// ── Modal de détail ──────────────────────────────────────────────────

function RevisionDetailModal({ revisionId, onClose, isModerator, currentUserEmail, onRefresh }) {
  const [revision, setRevision] = React.useState(null);
  const [currentBase, setCurrentBase] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState(null);
  const [reviewNote, setReviewNote] = React.useState("");
  const [submitting, setSubmitting] = React.useState(false);

  React.useEffect(() => {
    setLoading(true);
    (window.authedFetch || fetch)(`/api/get-revision?id=${encodeURIComponent(revisionId)}`)
      .then(r => r.ok ? r.json() : Promise.reject(r))
      .then(async (d) => {
        const rev = d.revision;
        setRevision(rev);
        // Récupère l'état actuel de la fiche pour le diff
        if (rev.action !== "create" && rev.plant_id) {
          const [ficheRes, photosRes] = await Promise.all([
            fetch(`/api/get?id=${encodeURIComponent(rev.plant_id)}`).then(r => r.ok ? r.json() : null),
            fetch(`/api/photos?id=${encodeURIComponent(rev.plant_id)}`).then(r => r.ok ? r.json() : null),
          ]);
          if (ficheRes && !ficheRes.error) {
            setCurrentBase({
              ...ficheRes,
              photos: (photosRes && !photosRes.error) ? photosRes : (ficheRes.photos || {}),
            });
          }
        }
        setLoading(false);
      })
      .catch(async (err) => {
        const msg = err.json ? (await err.json()).error : "Erreur de chargement";
        setError(msg);
        setLoading(false);
      });
  }, [revisionId]);

  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  const handleModerate = async (action) => {
    if (action === "reject" && !reviewNote.trim()) {
      if (!window.confirm("Refuser sans note de motivation ? Une note aide l'auteur à comprendre.")) return;
    }
    setSubmitting(true);
    try {
      const res = await (window.authedFetch || fetch)("/api/moderate-revision", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ id: revisionId, action, note: reviewNote.trim() || null }),
      });
      const j = await res.json();
      if (!res.ok || !j.ok) throw new Error(j.error || "Erreur serveur");
      if (window.__reloadPlants) window.__reloadPlants();
      onRefresh();
    } catch (e) {
      window.alert("Échec : " + (e.message || "erreur"));
      setSubmitting(false);
    }
  };

  const handleCancel = async () => {
    if (!window.confirm("Retirer votre proposition ? Cette action est définitive.")) return;
    setSubmitting(true);
    try {
      const res = await (window.authedFetch || fetch)("/api/cancel-revision", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ id: revisionId }),
      });
      const j = await res.json();
      if (!res.ok || !j.ok) throw new Error(j.error || "Erreur serveur");
      onRefresh();
    } catch (e) {
      window.alert("Échec : " + (e.message || "erreur"));
      setSubmitting(false);
    }
  };

  const isOwnRevision = revision && revision.author_email === currentUserEmail;
  const isPending = revision && revision.status === "pending";
  const canModerate = isModerator && isPending;
  const canCancel = isOwnRevision && isPending;

  return ReactDOM.createPortal(
    <div
      style={{ position: "fixed", inset: 0, background: "rgba(15,20,15,0.55)", backdropFilter: "blur(4px)", display: "grid", placeItems: "center", zIndex: 9999, padding: 20 }}
      onClick={onClose}
    >
      <div
        onClick={e => e.stopPropagation()}
        style={{
          background: "var(--paper)",
          padding: 0,
          width: "min(900px, 100%)",
          maxHeight: "92vh",
          display: "flex",
          flexDirection: "column",
          border: "1px solid var(--line)",
        }}
      >
        {/* Header */}
        <div style={{ padding: "24px 32px", borderBottom: "1px solid var(--line-soft)", display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 16 }}>
          <div>
            <div className="kicker" style={{ color: "var(--moss-deep)", marginBottom: 8 }}>
              {loading ? "Chargement…" : revision ? `Révision ${revision.status === "pending" ? "en attente" : revision.status}` : ""}
            </div>
            <h2 className="h-display" style={{ fontSize: 28, lineHeight: 1.1, margin: 0 }}>
              {revision ? revision.summary : "..."}
            </h2>
            {revision && (
              <div style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: ".10em", color: "var(--ink-mute)", marginTop: 8 }}>
                Soumise par {revision.author_email} · {formatTimeAgo(revision.created_at)}
                {revision.reviewed_at && ` · Examinée par ${revision.reviewed_by} ${formatTimeAgo(revision.reviewed_at)}`}
              </div>
            )}
          </div>
          <button onClick={onClose} aria-label="Fermer" style={{ background: "transparent", border: 0, fontSize: 26, color: "var(--ink-mute)", cursor: "pointer", padding: 4, lineHeight: 1 }}>×</button>
        </div>

        {/* Body scroll */}
        <div style={{ padding: "20px 32px", overflowY: "auto", flex: 1 }}>
          {loading ? (
            <p style={{ fontStyle: "italic", color: "var(--ink-mute)", textAlign: "center", padding: 40 }}>Chargement…</p>
          ) : error ? (
            <div style={{ padding: 16, background: "#fef3f2", borderLeft: "3px solid #d92d20" }}>
              <strong>Erreur :</strong> {error}
            </div>
          ) : revision && window.RevisionDiff ? (
            <window.RevisionDiff revision={revision} currentBase={currentBase} />
          ) : null}

          {/* Note de modération existante */}
          {revision && revision.review_note && (
            <div style={{ marginTop: 22, padding: "14px 18px", background: "var(--cream)", borderLeft: "3px solid var(--moss-deep)" }}>
              <div className="kicker" style={{ marginBottom: 6 }}>Note du modérateur</div>
              <p style={{ fontFamily: "var(--serif)", fontSize: 15, lineHeight: 1.5, color: "var(--ink-soft)", margin: 0 }}>{revision.review_note}</p>
            </div>
          )}
        </div>

        {/* Footer actions */}
        {(canModerate || canCancel) && (
          <div style={{ padding: "20px 32px", borderTop: "1px solid var(--line-soft)" }}>
            {canModerate && (
              <>
                <label style={{ display: "block", fontFamily: "var(--mono)", fontSize: 10, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--ink-mute)", marginBottom: 6 }}>
                  Note (optionnelle, transmise à l'auteur)
                </label>
                <textarea
                  value={reviewNote}
                  onChange={e => setReviewNote(e.target.value)}
                  placeholder="Ex. : merci pour l'enrichissement, j'ai juste ajusté la précaution sur la grossesse."
                  rows={3}
                  style={{
                    width: "100%", padding: "10px 14px",
                    fontFamily: "var(--serif)", fontSize: 15, color: "var(--ink)",
                    border: "1px solid var(--line)", background: "var(--cream)",
                    outline: "none", boxSizing: "border-box", resize: "vertical", marginBottom: 14,
                  }}
                />
                <div style={{ display: "flex", gap: 10, justifyContent: "flex-end" }}>
                  <button className="btn" disabled={submitting} onClick={() => handleModerate("reject")} style={{ borderColor: "#d92d20", color: "#b42318" }}>
                    Refuser
                  </button>
                  <button className="btn btn-solid" disabled={submitting} onClick={() => handleModerate("approve")} style={{ background: "#067647", borderColor: "#067647" }}>
                    {submitting ? "Application…" : "Approuver"}
                  </button>
                </div>
              </>
            )}
            {canCancel && !canModerate && (
              <div style={{ display: "flex", justifyContent: "flex-end" }}>
                <button className="btn" disabled={submitting} onClick={handleCancel} style={{ borderColor: "var(--rust)", color: "var(--rust)" }}>
                  {submitting ? "Annulation…" : "Retirer ma proposition"}
                </button>
              </div>
            )}
          </div>
        )}
      </div>
    </div>,
    document.body
  );
}

// ── Utils ────────────────────────────────────────────────────────────

function formatTimeAgo(iso) {
  if (!iso) return "";
  const d = new Date(iso);
  const diffMs = Date.now() - d.getTime();
  const diffMin = Math.floor(diffMs / 60000);
  if (diffMin < 1) return "à l'instant";
  if (diffMin < 60) return `il y a ${diffMin} min`;
  const diffH = Math.floor(diffMin / 60);
  if (diffH < 24) return `il y a ${diffH} h`;
  const diffD = Math.floor(diffH / 24);
  if (diffD < 7) return `il y a ${diffD} j`;
  return d.toLocaleDateString("fr-FR", { day: "numeric", month: "short", year: "numeric" });
}

window.Moderation = Moderation;
