/* ──────────────────────────────────────────────────────────────────────
   capability-templates.jsx — perms v2 (feedback b030cab9)
   ──────────────────────────────────────────────────────────────────────
   Full-page CRUD for org-scoped permission templates. Platform-default
   templates (organisation_id IS NULL) are shown read-only at the top so
   org admins can clone and tweak them.

   Mounted at #permission-templates. Visible in the sidebar to anyone who
   holds the users.invite capability (the only people who can use templates
   in the first place). Greying / disabled buttons enforced server-side.
   ────────────────────────────────────────────────────────────────────── */

function CapabilityTemplatesScreen() {
  const [tpls, setTpls] = useState([]);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState(null);
  const [editing, setEditing] = useState(null); // template object | { __new: true }
  const [callerCaps, setCallerCaps] = useState([]);
  const [callerRole, setCallerRole] = useState(null);

  /* Pull caller caps so we can grey the "edit/delete" buttons on platform
     templates when the caller isn't aquaos_admin. The capability funnel is
     enforced server-side regardless. */
  function load() {
    setLoading(true);
    setErr(null);
    Promise.all([
      apiFetch('/api/capabilities/templates'),
      apiFetch('/api/capabilities/me'),
    ]).then(([tplRes, meRes]) => {
      setTpls(tplRes.templates || []);
      setCallerCaps(meRes.capabilities || []);
      setCallerRole(meRes.role || null);
      setLoading(false);
    }).catch((e) => { setErr(e.message); setLoading(false); });
  }

  useEffect(load, []);

  function newTemplate() {
    setEditing({ __new: true, name: '', description: '', capabilities: [] });
  }

  async function deleteTpl(t) {
    if (!window.confirm(`Delete role "${t.name}"? This cannot be undone.`)) return;
    try {
      await apiFetch(`/api/capabilities/templates/${t.id}`, { method: 'DELETE' });
      window.toast && window.toast.success('Template deleted');
      load();
    } catch (e) { window.toast && window.toast.error(e.message); }
  }

  async function clonePlatform(t) {
    /* Clone-into-org: create a new org-scoped template seeded from the
       platform default. We use the existing POST endpoint which returns
       the new id; the server caps capabilities to the caller's set. */
    setEditing({
      __new: true,
      name: `${t.name} (copy)`,
      description: t.description || '',
      capabilities: (t.capabilities || []).slice(),
    });
  }

  if (loading) {
    return <div style={{ padding: 28, color: 'var(--aq-text-faint)' }}>Loading templates…</div>;
  }
  if (err) {
    return <div style={{ padding: 28, color: 'var(--aq-danger)' }}>{err}</div>;
  }

  const platformTpls = tpls.filter((t) => t.organisation_id === null);
  const orgTpls = tpls.filter((t) => t.organisation_id !== null);
  const canCreate = callerRole === 'aquaos_admin' || callerCaps.includes('users.invite');

  return (
    <div className="aq-page" style={{ padding: 24, maxWidth: 920, margin: '0 auto' }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 14, marginBottom: 22,
      }}>
        <h1 style={{ flex: 1, margin: 0, fontSize: 20, color: 'var(--aq-text)', fontWeight: 500 }}>
          Roles
        </h1>
        {canCreate && (
          <button className="x-btn" onClick={newTemplate}>+ New role</button>
        )}
      </div>

      <p style={{ color: 'var(--aq-text-faint)', fontSize: 12.5, margin: '0 0 22px', maxWidth: 600 }}>
        A role is a saved set of capabilities. Apply one when inviting a
        teammate, and they pick up the same set automatically. Platform
        defaults below are shipped with Slate — clone one to make an
        org-specific role.
      </p>

      <SectionTpl
        title="Platform defaults"
        helper="Shipped with Slate — read-only unless you're a platform admin."
        templates={platformTpls}
        callerRole={callerRole}
        readOnly={callerRole !== 'aquaos_admin'}
        onEdit={(t) => setEditing(t)}
        onDelete={callerRole === 'aquaos_admin' ? deleteTpl : null}
        onClone={canCreate ? clonePlatform : null}
      />

      <div style={{ height: 18 }} />

      <SectionTpl
        title="Your organisation's roles"
        helper="Custom roles your team has saved. Used in the invite flow."
        templates={orgTpls}
        callerRole={callerRole}
        readOnly={false}
        onEdit={canCreate ? ((t) => setEditing(t)) : null}
        onDelete={canCreate ? deleteTpl : null}
        onClone={null}
      />

      {editing && (
        <TemplateEditModal
          tpl={editing}
          onClose={() => setEditing(null)}
          onSaved={() => { setEditing(null); load(); }}
        />
      )}
    </div>
  );
}

function SectionTpl({ title, helper, templates, callerRole, readOnly, onEdit, onDelete, onClone }) {
  return (
    <section>
      <h2 style={{
        fontSize: 11.5, letterSpacing: 0.6, textTransform: 'uppercase',
        color: 'var(--aq-text-faint)', margin: '0 0 6px',
      }}>{title}</h2>
      <div style={{ fontSize: 12, color: 'var(--aq-text-faint)', marginBottom: 12 }}>{helper}</div>
      {templates.length === 0 ? (
        <div style={{
          padding: '14px 16px', borderRadius: 8,
          border: '1px dashed var(--aq-line)', color: 'var(--aq-text-faint)', fontSize: 12.5,
        }}>No templates yet.</div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {templates.map((t) => (
            <div
              key={t.id}
              style={{
                display: 'flex', alignItems: 'center', gap: 14,
                padding: '12px 14px', borderRadius: 8,
                background: 'var(--aq-surface)', border: '1px solid var(--aq-line)',
              }}
            >
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{
                  fontSize: 13.5, color: 'var(--aq-text)', fontWeight: 500,
                  overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                }}>{t.name}</div>
                {t.description && (
                  <div style={{ fontSize: 11.5, color: 'var(--aq-text-faint)', marginTop: 2 }}>{t.description}</div>
                )}
                <div style={{ fontSize: 11, color: 'var(--aq-text-faint)', marginTop: 4 }}>
                  {(t.capabilities || []).length} capabilities
                </div>
              </div>
              <div style={{ display: 'flex', gap: 6 }}>
                {onClone && t.organisation_id === null && (
                  <button className="x-btn ghost" onClick={() => onClone(t)}>Clone</button>
                )}
                {onEdit && !readOnly && (
                  <button className="x-btn ghost" onClick={() => onEdit(t)}>Edit</button>
                )}
                {onDelete && (
                  <button className="x-btn ghost" onClick={() => onDelete(t)} style={{ color: 'var(--aq-danger)' }}>Delete</button>
                )}
              </div>
            </div>
          ))}
        </div>
      )}
    </section>
  );
}

function TemplateEditModal({ tpl, onClose, onSaved }) {
  const isNew = !!tpl.__new;
  const [name, setName] = useState(tpl.name || '');
  const [description, setDescription] = useState(tpl.description || '');
  const [caps, setCaps] = useState(Array.isArray(tpl.capabilities) ? tpl.capabilities.slice() : []);
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState(null);

  async function save() {
    if (!name.trim()) { setErr('Name is required.'); return; }
    setBusy(true); setErr(null);
    try {
      if (isNew) {
        await apiFetch('/api/capabilities/templates', {
          method: 'POST',
          body: JSON.stringify({ name: name.trim(), description, capabilities: caps }),
        });
      } else {
        await apiFetch(`/api/capabilities/templates/${tpl.id}`, {
          method: 'PUT',
          body: JSON.stringify({ name: name.trim(), description, capabilities: caps }),
        });
      }
      onSaved && onSaved();
    } catch (e) { setErr(e.message); }
    finally { setBusy(false); }
  }

  return (
    <US_ModalShell open={true} title={isNew ? 'New role' : `Edit "${tpl.name}"`} onClose={onClose} width={620}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        <label style={{ display: 'block' }}>
          <div style={{ fontSize: 11.5, color: 'var(--aq-text-dim)', marginBottom: 5 }}>Role name</div>
          <input
            type="text"
            value={name}
            onChange={(e) => setName(e.target.value)}
            placeholder="e.g. Front-of-house operator"
            style={{
              width: '100%', padding: '8px 10px', fontSize: 13,
              background: 'var(--aq-surface-2)', border: '1px solid var(--aq-line)',
              borderRadius: 7, color: 'var(--aq-text)', font: 'inherit', outline: 0,
            }}
          />
        </label>
        <label style={{ display: 'block' }}>
          <div style={{ fontSize: 11.5, color: 'var(--aq-text-dim)', marginBottom: 5 }}>Description <span style={{ color: 'var(--aq-text-faint)' }}>(optional)</span></div>
          <textarea
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            placeholder="What this set is for, who it's intended for…"
            rows={2}
            style={{
              width: '100%', padding: '8px 10px', fontSize: 12.5,
              background: 'var(--aq-surface-2)', border: '1px solid var(--aq-line)',
              borderRadius: 7, color: 'var(--aq-text)', font: 'inherit', outline: 0,
              resize: 'vertical',
            }}
          />
        </label>

        <div>
          <div style={{ fontSize: 11.5, color: 'var(--aq-text-dim)', marginBottom: 5 }}>Capabilities</div>
          {window.CapabilityGrid ? (
            <CapabilityGrid
              value={caps}
              onChange={setCaps}
              hideTemplates={true}
              hideSaveAs={true}
            />
          ) : (
            <div style={{ color: 'var(--aq-text-faint)', fontSize: 12 }}>Capability grid not loaded.</div>
          )}
        </div>

        {err && (
          <div style={{
            padding: '8px 10px', borderRadius: 6,
            background: 'color-mix(in srgb, var(--aq-danger) 12%, transparent)',
            color: 'var(--aq-danger)', fontSize: 12,
          }}>{err}</div>
        )}
        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 4 }}>
          <button className="x-btn ghost" onClick={onClose}>Cancel</button>
          <button className="x-btn" onClick={save} disabled={busy}>
            {busy ? 'Saving…' : (isNew ? 'Create template' : 'Save changes')}
          </button>
        </div>
      </div>
    </US_ModalShell>
  );
}

window.CapabilityTemplatesScreen = CapabilityTemplatesScreen;
