/* global React, Icon, Modal */
const { useState: useStateO, useEffect: useEffectO } = React;

// ============================================================================
// ORGANIZATIONS — super-admin tool to create / archive / delete organizations
// ----------------------------------------------------------------------------
// Visible only to users with the "orgs.manage" permission. Backed by the
// "organizations_super_admin_*" RLS policies in organizations-super-admin.sql.
// ============================================================================

function Organizations({ t, lang }) {
  const { has, loading: permsLoading } = window.melr.useCurrentUserPermissions();
  const { data: orgs, loading, realtime, refresh } = window.melr.useAllOrganizations();
  const LiveBadge = window.melr.LiveBadge;
  const [editing, setEditing]   = useStateO(null);    // "new" | org row | null
  const [confirming, setConfirming] = useStateO(null); // org pending hard-delete
  const [showArchived, setShowArchived] = useStateO(false);
  const [busyId, setBusyId]     = useStateO(null);

  if (permsLoading) {
    return <div className="page"><div style={{ padding: 28 }}>{lang === "fr" ? "Chargement…" : "Loading…"}</div></div>;
  }
  if (!has("orgs.manage")) {
    return (
      <div className="page">
        <div className="page-header">
          <div className="page-eyebrow">{lang === "fr" ? "ADMINISTRATION" : "ADMINISTRATION"}</div>
          <h1 className="page-title">{lang === "fr" ? "Organisations" : "Organizations"}</h1>
        </div>
        <div className="card" style={{ marginTop: 16, padding: 24 }}>
          <div className="text-faint" style={{ textAlign: "center" }}>
            {lang === "fr"
              ? "Accès réservé aux super-administrateurs (permission orgs.manage)."
              : "Super-admins only (orgs.manage permission required)."}
          </div>
        </div>
      </div>
    );
  }

  const onToggleArchive = async (org) => {
    setBusyId(org.id);
    try {
      if (org.archived_at) await window.melr.organizationsCrud.unarchive(org.id);
      else                 await window.melr.organizationsCrud.archive(org.id);
      await refresh();
    } catch (e) { window.alert((lang === "fr" ? "Erreur : " : "Error: ") + e.message); }
    finally { setBusyId(null); }
  };

  const visible = (orgs || []).filter((o) => showArchived ? true : !o.archived_at);
  const archivedCount = (orgs || []).filter((o) => !!o.archived_at).length;

  return (
    <div className="page">
      <div className="page-header">
        <div className="page-eyebrow">{lang === "fr" ? "SUPER-ADMINISTRATION" : "SUPER-ADMIN"}</div>
        <div className="page-header-row">
          <div>
            <h1 className="page-title">
              {lang === "fr" ? "Organisations" : "Organizations"}{" "}
              <LiveBadge on={realtime} lang={lang} />
            </h1>
            <div className="page-sub">
              {lang === "fr"
                ? "Toutes les organisations de la plateforme. Création, archivage et suppression sont irréversibles côté données."
                : "Every organization on the platform. Creation, archiving and deletion are data-irreversible."}
            </div>
          </div>
          <div className="page-header-actions">
            <button className="btn sm primary" onClick={() => setEditing("new")}>
              <Icon.plus /> {lang === "fr" ? "Nouvelle organisation" : "New organization"}
            </button>
          </div>
        </div>
      </div>

      <div className="card">
        <div className="card-head">
          <div className="card-title">
            {lang === "fr" ? "Liste" : "List"}{" "}
            <span className="tag-mono" style={{ marginLeft: 6 }}>{visible.length} / {(orgs || []).length}</span>
          </div>
          <div style={{ flex: 1 }} />
          {archivedCount > 0 && (
            <label style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 11.5, cursor: "pointer" }}>
              <input type="checkbox" checked={showArchived} onChange={(e) => setShowArchived(e.target.checked)} />
              {lang === "fr" ? "Inclure les archivées" : "Include archived"}{" "}
              <span className="tag-mono" style={{ marginLeft: 4 }}>{archivedCount}</span>
            </label>
          )}
        </div>
        <div className="card-body flush">
          {loading ? (
            <div className="text-faint" style={{ padding: 24, textAlign: "center" }}>{lang === "fr" ? "Chargement…" : "Loading…"}</div>
          ) : visible.length === 0 ? (
            <div className="text-faint" style={{ padding: 24, textAlign: "center" }}>
              {lang === "fr"
                ? "Aucune organisation. Cliquez « Nouvelle organisation » pour démarrer."
                : "No organization yet. Click 'New organization' to start."}
            </div>
          ) : (
            <table className="tbl">
              <thead>
                <tr>
                  <th>{lang === "fr" ? "Nom" : "Name"}</th>
                  <th>Slug</th>
                  <th>{lang === "fr" ? "Langue" : "Locale"}</th>
                  <th className="num">{lang === "fr" ? "Membres" : "Members"}</th>
                  <th className="num">{lang === "fr" ? "Projets" : "Projects"}</th>
                  <th>{lang === "fr" ? "Statut" : "State"}</th>
                  <th>{lang === "fr" ? "Créée le" : "Created"}</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {visible.map((o) => (
                  <tr key={o.id} style={{ opacity: o.archived_at ? 0.55 : 1 }}>
                    <td>
                      <div className="strong">{o.name}</div>
                      {o.logo_url && <div className="text-faint" style={{ fontSize: 10 }}>{o.logo_url}</div>}
                    </td>
                    <td className="mono">{o.slug}</td>
                    <td className="mono text-faint">{(o.default_locale || "—").toUpperCase()}</td>
                    <td className="num mono">{o.members_count}</td>
                    <td className="num mono">{o.projects_count}</td>
                    <td>
                      {o.archived_at
                        ? <span className="pill" style={{ background: "#fef3c7", color: "#92400e", fontSize: 10.5 }}>{lang === "fr" ? "Archivée" : "Archived"}</span>
                        : <span className="pill green dot" style={{ fontSize: 10.5 }}>{lang === "fr" ? "Active" : "Active"}</span>}
                    </td>
                    <td className="text-faint" style={{ fontSize: 11 }}>
                      {o.created_at ? new Date(o.created_at).toLocaleDateString(lang === "fr" ? "fr-FR" : "en-US") : "—"}
                    </td>
                    <td>
                      <div className="row gap-xs" style={{ justifyContent: "flex-end" }}>
                        <button className="btn xs" onClick={() => setEditing(o)}>
                          <Icon.edit /> {lang === "fr" ? "Modifier" : "Edit"}
                        </button>
                        <button className="btn xs ghost" onClick={() => onToggleArchive(o)} disabled={busyId === o.id}
                          title={o.archived_at
                            ? (lang === "fr" ? "Restaurer" : "Restore")
                            : (lang === "fr" ? "Archiver (réversible)" : "Archive (reversible)")}>
                          {o.archived_at
                            ? (lang === "fr" ? "Restaurer" : "Restore")
                            : (lang === "fr" ? "Archiver" : "Archive")}
                        </button>
                        <button className="btn xs ghost" onClick={() => setConfirming(o)} disabled={busyId === o.id}
                          title={lang === "fr" ? "Supprimer (irréversible)" : "Delete (irreversible)"}
                          style={{ color: "#b91c1c" }}>
                          <Icon.x />
                        </button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>
      </div>

      <div className="text-faint" style={{ fontSize: 11, marginTop: 12, lineHeight: 1.55 }}>
        {lang === "fr"
          ? "💡 Archiver est réversible : les données restent intactes, l'organisation devient masquée par défaut. Supprimer est définitif : cascade sur tous les projets, membres, indicateurs, formulaires, saisies, audits et rapports de l'org."
          : "💡 Archive is reversible: data stays, the org is hidden by default. Delete is permanent: cascades to every project, member, indicator, form, submission, audit and report of the org."}
      </div>

      {editing && (
        <OrgEditor
          lang={lang}
          existing={editing === "new" ? null : editing}
          onClose={() => setEditing(null)}
          onSaved={refresh}
        />
      )}
      {confirming && (
        <OrgDeleteModal
          lang={lang}
          org={confirming}
          onClose={() => setConfirming(null)}
          onDeleted={refresh}
        />
      )}
    </div>
  );
}

// ── Create / edit modal ────────────────────────────────────────────────────
function OrgEditor({ lang, existing, onClose, onSaved }) {
  const isNew = !existing;
  const [name, setName]           = useStateO(existing ? existing.name : "");
  const [slug, setSlug]           = useStateO(existing ? existing.slug : "");
  const [locale, setLocale]       = useStateO(existing ? (existing.default_locale || "fr") : "fr");
  const [logoUrl, setLogoUrl]     = useStateO(existing ? (existing.logo_url || "") : "");
  const [busy, setBusy]           = useStateO(false);
  const [err, setErr]             = useStateO(null);
  const [slugManuallyEdited, setSlugManuallyEdited] = useStateO(!isNew);

  // Auto-derive slug from name as the user types (until they touch slug)
  const onNameChange = (v) => {
    setName(v);
    if (!slugManuallyEdited) {
      const auto = v.toLowerCase()
        .normalize("NFD").replace(/[̀-ͯ]/g, "")
        .replace(/[^a-z0-9]+/g, "-")
        .replace(/^-+|-+$/g, "")
        .slice(0, 48);
      setSlug(auto);
    }
  };

  const onSubmit = async (e) => {
    e.preventDefault();
    if (!name.trim()) { setErr(lang === "fr" ? "Nom requis." : "Name required."); return; }
    if (!slug.trim()) { setErr(lang === "fr" ? "Slug requis." : "Slug required."); return; }
    setBusy(true); setErr(null);
    try {
      const payload = {
        name: name.trim(),
        slug: slug.trim(),
        default_locale: locale || "fr",
        logo_url: logoUrl.trim() || null,
      };
      if (isNew) await window.melr.organizationsCrud.create(payload);
      else       await window.melr.organizationsCrud.update(existing.id, payload);
      if (onSaved) await onSaved();
      onClose();
    } catch (e2) { setErr(e2.message); }
    finally { setBusy(false); }
  };

  const inp = { width: "100%", padding: "8px 10px", borderRadius: 6, border: "1px solid var(--line)", fontSize: 13, background: "var(--bg, white)", color: "var(--text)", boxSizing: "border-box", fontFamily: "inherit" };
  const lbl = { display: "block", fontSize: 11, color: "var(--text-faint)", marginBottom: 4, textTransform: "uppercase", letterSpacing: "0.04em" };

  return (
    <Modal
      title={isNew
        ? (lang === "fr" ? "Nouvelle organisation" : "New organization")
        : (lang === "fr" ? "Modifier : " + existing.slug : "Edit: " + existing.slug)}
      onClose={onClose}
      onSubmit={onSubmit}
      footer={<>
        <button type="button" className="btn sm ghost" onClick={onClose} disabled={busy}>
          {lang === "fr" ? "Annuler" : "Cancel"}
        </button>
        <button type="submit" className="btn sm primary" disabled={busy}>
          {busy ? "…" : (isNew ? (lang === "fr" ? "Créer" : "Create") : (lang === "fr" ? "Enregistrer" : "Save"))}
        </button>
      </>}>
      <div style={{ display: "grid", gap: 12 }}>
        <div>
          <label style={lbl}>{lang === "fr" ? "Nom *" : "Name *"}</label>
          <input style={inp} value={name} onChange={(e) => onNameChange(e.target.value)}
            placeholder={lang === "fr" ? "Mon Organisation" : "My Organization"}
            required maxLength={120} />
        </div>
        <div>
          <label style={lbl}>{lang === "fr" ? "Slug * (URL-friendly)" : "Slug * (URL-friendly)"}</label>
          <input style={inp} value={slug}
            onChange={(e) => { setSlugManuallyEdited(true); setSlug(e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, "-")); }}
            placeholder="mon-orga" required maxLength={48} />
          <div className="text-faint" style={{ fontSize: 10.5, marginTop: 4 }}>
            {lang === "fr"
              ? "Minuscules, chiffres, tirets uniquement. Auto-généré depuis le nom."
              : "Lowercase, digits, hyphens only. Auto-generated from the name."}
          </div>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
          <div>
            <label style={lbl}>{lang === "fr" ? "Langue par défaut" : "Default locale"}</label>
            <select style={inp} value={locale} onChange={(e) => setLocale(e.target.value)}>
              <option value="fr">Français (FR)</option>
              <option value="en">English (EN)</option>
              <option value="es">Español (ES)</option>
              <option value="pt">Português (PT)</option>
            </select>
          </div>
          <div>
            <label style={lbl}>{lang === "fr" ? "URL logo (optionnel)" : "Logo URL (optional)"}</label>
            <input style={inp} value={logoUrl} onChange={(e) => setLogoUrl(e.target.value)}
              placeholder="https://…/logo.png" />
          </div>
        </div>
        {isNew && (
          <div style={{ padding: "10px 12px", background: "#eef2ff", color: "#3730a3", borderRadius: 6, fontSize: 12 }}>
            {lang === "fr"
              ? "ℹ️ Après création, ajoutez le premier admin de l'org via 'Org & rôles' → 'Inscrits en attente' (il doit d'abord créer son compte depuis le panneau de connexion)."
              : "ℹ️ After creation, add the first admin via 'Org & roles' → 'Pending sign-ups' (they must first create their account from the auth panel)."}
          </div>
        )}
        {err && (
          <div style={{ padding: "8px 10px", background: "#fee2e2", color: "#991b1b", borderRadius: 6, fontSize: 12.5 }}>{err}</div>
        )}
      </div>
    </Modal>
  );
}

// ── Hard-delete confirmation modal ─────────────────────────────────────────
// Requires the user to re-type the slug to proceed. Defends against accidental
// cascade deletion of all org-scoped data.
function OrgDeleteModal({ lang, org, onClose, onDeleted }) {
  const [typed, setTyped] = useStateO("");
  const [busy, setBusy]   = useStateO(false);
  const [err, setErr]     = useStateO(null);
  const matches = typed.trim() === org.slug;

  const onConfirm = async () => {
    if (!matches) return;
    setBusy(true); setErr(null);
    try {
      await window.melr.organizationsCrud.remove(org.id, org.slug);
      if (onDeleted) await onDeleted();
      onClose();
    } catch (e2) { setErr(e2.message); }
    finally { setBusy(false); }
  };

  const inp = { width: "100%", padding: "8px 10px", borderRadius: 6, border: "1px solid var(--line)", fontSize: 13, fontFamily: "ui-monospace, monospace" };
  return (
    <Modal
      title={<>⚠ {lang === "fr" ? "Supprimer l'organisation" : "Delete organization"}</>}
      onClose={onClose}
      footer={<>
        <button type="button" className="btn sm ghost" onClick={onClose} disabled={busy}>
          {lang === "fr" ? "Annuler" : "Cancel"}
        </button>
        <button type="button" onClick={onConfirm} disabled={busy || !matches}
          style={{
            padding: "8px 14px", borderRadius: 6, border: 0,
            background: matches ? "#dc2626" : "#9ca3af",
            color: "white", cursor: matches ? "pointer" : "not-allowed", fontWeight: 600,
          }}>
          {busy ? "…" : (lang === "fr" ? "Supprimer définitivement" : "Permanently delete")}
        </button>
      </>}>
      <div style={{ display: "grid", gap: 12 }}>
        <div className="strong" style={{ color: "#991b1b" }}>
          {lang === "fr" ? "Action irréversible — cascade sur toutes les données" : "Irreversible — cascades to every record"}
        </div>
        <div className="text-faint" style={{ fontSize: 12.5, lineHeight: 1.55 }}>
          {lang === "fr"
            ? "Cette action supprime définitivement l'organisation « " + org.name + " » ainsi que TOUS ses projets, sites, indicateurs, formulaires, saisies, audits, validations, rapports, tickets et profils membres. Aucun retour possible sans sauvegarde."
            : "This permanently removes the organization '" + org.name + "' and ALL its projects, sites, indicators, forms, submissions, audits, validations, reports, tickets and member profiles. No undo without a backup."}
        </div>
        <div>
          <label style={{ display: "block", fontSize: 11, color: "var(--text-faint)", marginBottom: 4, textTransform: "uppercase", letterSpacing: "0.04em" }}>
            {lang === "fr"
              ? <>Pour confirmer, retape le slug : <span className="mono strong" style={{ color: "#991b1b" }}>{org.slug}</span></>
              : <>To confirm, retype the slug: <span className="mono strong" style={{ color: "#991b1b" }}>{org.slug}</span></>}
          </label>
          <input style={inp} value={typed} onChange={(e) => setTyped(e.target.value)}
            placeholder={org.slug} autoFocus />
        </div>
        {err && (
          <div style={{ padding: "8px 10px", background: "#fee2e2", color: "#991b1b", borderRadius: 6, fontSize: 12.5 }}>{err}</div>
        )}
      </div>
    </Modal>
  );
}

window.Organizations = Organizations;
