// admin.jsx — Users Management (+ modals) and Integrations pages
const { useState: useStateA } = React;

/* ---------- generic modal ---------- */
function Modal({ title, subtitle, icon, onClose, children, width = 440 }) {
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-zinc-900/40 backdrop-blur-[1px] animate-[toastin_0.15s_ease]" onClick={onClose}>
      <div className="bg-white rounded-2xl shadow-2xl border border-zinc-200 w-full overflow-hidden" style={{ maxWidth: width }} onClick={e => e.stopPropagation()}>
        <div className="flex items-start gap-3 px-5 pt-5 pb-4 border-b border-zinc-100">
          {icon && <div className="flex items-center justify-center w-9 h-9 rounded-lg shrink-0" style={{ background: "var(--accent-wash)", color: "var(--accent)" }}><Icon name={icon} size={18} /></div>}
          <div className="min-w-0 flex-1">
            <h3 className="text-[15px] font-semibold text-zinc-900">{title}</h3>
            {subtitle && <p className="text-[12.5px] text-zinc-500 mt-0.5">{subtitle}</p>}
          </div>
          <button onClick={onClose} className="w-8 h-8 -mr-1 -mt-1 flex items-center justify-center rounded-lg text-zinc-400 hover:bg-zinc-100"><Icon name="x" size={18} /></button>
        </div>
        {children}
      </div>
    </div>
  );
}

function RoleBadge({ role }) {
  const r = ROLES[role];
  return (
    <span className="inline-flex items-center gap-1.5 rounded-md px-2 py-0.5 text-[11.5px] font-medium" style={{ background: r.color + "14", color: r.color }}>
      <span className="w-1.5 h-1.5 rounded-full" style={{ background: r.color }} />{r.label}
    </span>
  );
}

const USTATUS = {
  active:   { label: "Active",   color: "#15803d", bg: "#f0fdf4", dot: "#22c55e" },
  invited:  { label: "Invited",  color: "#a16207", bg: "#fefce8", dot: "#eab308" },
  disabled: { label: "Disabled", color: "#71717a", bg: "#f4f4f5", dot: "#a1a1aa" },
};

/* ---------- Users page ---------- */
function UsersPage({ canManage, onToast }) {
  const [users, setUsers] = useStateA(USERS);
  const [editing, setEditing] = useStateA(null);
  const [inviting, setInviting] = useStateA(false);
  const [q, setQ] = useStateA("");
  const [roleFilter, setRoleFilter] = useStateA("all");
  const [menu, setMenu] = useStateA(null);

  // load real users from Supabase profiles on mount
  React.useEffect(() => {
    sb.from("profiles")
      .select("id, name, initials, color, role, dept, status")
      .then(({ data, error }) => {
        if (data && data.length > 0) {
          // merge with auth info — map to display shape
          setUsers(data.map(p => ({
            id: p.id,
            name: p.name || "Unknown",
            email: "",           // fetched separately below
            initials: p.initials,
            color: p.color,
            role: p.role,
            dept: p.dept || "—",
            last: "—",
            status: p.status || "active",
          })));
        }
      });
  }, []);

  const rows = users.filter(u => {
    if (roleFilter !== "all" && u.role !== roleFilter) return false;
    if (q && !(u.name + u.email + u.dept).toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  });

  async function saveRole(id, role) {
    const { error } = await sb.from("profiles").update({ role }).eq("id", id);
    if (error) { onToast("Failed to update role", { tone: "danger", icon: "alert" }); return; }
    setUsers(us => us.map(u => u.id === id ? { ...u, role } : u));
    setEditing(null);
    onToast(`Role updated`, { icon: "check" });
  }
  async function toggleDisable(u) {
    const newStatus = u.status === "disabled" ? "active" : "disabled";
    const { error } = await sb.from("profiles").update({ status: newStatus }).eq("id", u.id);
    if (error) { onToast("Failed to update account", { tone: "danger", icon: "alert" }); setMenu(null); return; }
    setUsers(us => us.map(x => x.id === u.id ? { ...x, status: newStatus } : x));
    setMenu(null);
    onToast(newStatus === "active" ? `${u.name} re-enabled` : `${u.name}'s account disabled`, { tone: newStatus === "active" ? "ok" : "warn", icon: newStatus === "active" ? "check" : "ban" });
  }
  async function sendReset(u) {
    setMenu(null);
    const { error } = await sb.auth.resetPasswordForEmail(u.email, { redirectTo: window.location.origin });
    if (error) { onToast("Failed to send reset email", { tone: "danger", icon: "alert" }); return; }
    onToast(`Password reset sent to ${u.name}`, { icon: "mail" });
  }
  async function invite(email, name, role, dept) {
    try {
      const { data: { session } } = await sb.auth.getSession();
      const res = await fetch(
        "https://vankxqpmdlajpuivpsku.supabase.co/functions/v1/invite-user",
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${session.access_token}`,
          },
          body: JSON.stringify({ email, name, role, dept }),
        }
      );
      const json = await res.json();
      if (json.error) throw new Error(json.error);
      // add to local list optimistically
      const initials = name.split(" ").map(w => w[0]).join("").slice(0, 2).toUpperCase();
      setUsers(us => [{ id: json.userId, name, email, role, dept, last: "Pending", status: "invited", color: "#0891b2", initials }, ...us]);
      setInviting(false);
      onToast(`Invite sent to ${email}`, { icon: "send" });
    } catch (err) {
      onToast(err.message || "Failed to send invite", { tone: "danger", icon: "alert" });
    }
  }

  return (
    <div className="p-6">
      <div className="flex items-start gap-3 mb-4 flex-wrap">
        <div>
          <h2 className="text-[15px] font-semibold text-zinc-900 tracking-tight">Users &amp; Access</h2>
          <p className="text-[12.5px] text-zinc-500 mt-0.5">{users.filter(u=>u.status==="active").length} active · {users.filter(u=>u.status==="invited").length} invited · {users.filter(u=>u.status==="disabled").length} disabled</p>
        </div>
        {canManage && <div className="ml-auto"><Button variant="primary" size="md" icon="plus" onClick={() => setInviting(true)}>Invite User</Button></div>}
      </div>

      <div className="bg-white rounded-xl border border-zinc-200 overflow-hidden">
        <div className="flex items-center gap-2.5 px-4 py-3 border-b border-zinc-200 flex-wrap">
          <div className="flex items-center gap-2 w-60 h-8 px-2.5 rounded-lg bg-zinc-100/80 border border-transparent focus-within:bg-white focus-within:border-zinc-300 transition-colors">
            <Icon name="search" size={15} className="text-zinc-400" />
            <input value={q} onChange={e => setQ(e.target.value)} placeholder="Search users…" className="bg-transparent outline-none text-[12.5px] text-zinc-700 placeholder:text-zinc-400 w-full" />
          </div>
          <SelectMini icon="shield" value={roleFilter} onChange={setRoleFilter} options={[{ v: "all", label: "All roles" }, ...Object.values(ROLES).map(r => ({ v: r.key, label: r.label }))]} />
          <span className="ml-auto text-[12px] text-zinc-400">{rows.length} user{rows.length !== 1 ? "s" : ""}</span>
        </div>

        <div className="overflow-x-auto">
          <table className="w-full border-collapse min-w-[860px]">
            <thead>
              <tr className="border-b border-zinc-200">
                {["User", "Role", "Department", "Last Active", "Status", ""].map((h, i) => (
                  <th key={i} className="text-left px-4 py-2.5 text-[11px] font-semibold uppercase tracking-wider text-zinc-400 whitespace-nowrap">{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {rows.map(u => (
                <tr key={u.id} className={`border-b border-zinc-100 hover:bg-zinc-50 transition-colors ${u.status === "disabled" ? "opacity-60" : ""}`}>
                  <td className="px-4 py-3">
                    <div className="flex items-center gap-2.5">
                      <Avatar person={u} size={32} />
                      <div className="leading-tight">
                        <div className="text-[13px] font-medium text-zinc-800">{u.name}</div>
                        <div className="text-[11.5px] text-zinc-400">{u.email}</div>
                      </div>
                    </div>
                  </td>
                  <td className="px-4 py-3"><RoleBadge role={u.role} /></td>
                  <td className="px-4 py-3"><span className="text-[12.5px] text-zinc-600">{u.dept}</span></td>
                  <td className="px-4 py-3"><span className="text-[12.5px] text-zinc-500 tabular-nums">{u.last}</span></td>
                  <td className="px-4 py-3">
                    <span className="inline-flex items-center gap-1.5 rounded-md px-2 py-0.5 text-[11.5px] font-medium" style={{ background: USTATUS[u.status].bg, color: USTATUS[u.status].color }}>
                      <span className="w-1.5 h-1.5 rounded-full" style={{ background: USTATUS[u.status].dot }} />{USTATUS[u.status].label}
                    </span>
                  </td>
                  <td className="px-4 py-3 text-right relative">
                    {canManage ? (
                      <div className="inline-flex items-center gap-1">
                        <button onClick={() => setEditing(u)} className="inline-flex items-center gap-1.5 px-2 py-1 rounded-md text-[12px] font-medium text-zinc-600 hover:bg-zinc-100"><Icon name="edit" size={13} /> Edit</button>
                        <button onClick={() => setMenu(menu === u.id ? null : u.id)} className="w-7 h-7 rounded-md flex items-center justify-center text-zinc-400 hover:bg-zinc-100"><Icon name="dots" size={16} /></button>
                        {menu === u.id && (
                          <>
                            <div className="fixed inset-0 z-10" onClick={() => setMenu(null)} />
                            <div className="absolute right-0 top-9 z-20 w-44 bg-white rounded-lg border border-zinc-200 shadow-lg py-1 text-left">
                              <button onClick={() => { setEditing(u); setMenu(null); }} className="w-full flex items-center gap-2 px-3 py-2 text-[12.5px] text-zinc-700 hover:bg-zinc-50"><Icon name="key" size={14} className="text-zinc-400" /> Change role</button>
                              <button onClick={() => sendReset(u)} className="w-full flex items-center gap-2 px-3 py-2 text-[12.5px] text-zinc-700 hover:bg-zinc-50"><Icon name="mail" size={14} className="text-zinc-400" /> Send reset link</button>
                              <div className="my-1 border-t border-zinc-100" />
                              <button onClick={() => toggleDisable(u)} className={`w-full flex items-center gap-2 px-3 py-2 text-[12.5px] hover:bg-zinc-50 ${u.status === "disabled" ? "text-emerald-600" : "text-red-600"}`}>
                                <Icon name={u.status === "disabled" ? "check" : "ban"} size={14} /> {u.status === "disabled" ? "Re-enable account" : "Disable account"}
                              </button>
                            </div>
                          </>
                        )}
                      </div>
                    ) : <span className="text-[12px] text-zinc-300">—</span>}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      {editing && <EditRoleModal user={editing} onClose={() => setEditing(null)} onSave={saveRole} />}
      {inviting && <InviteModal onClose={() => setInviting(false)} onInvite={(email, name, role, dept) => invite(email, name, role, dept)} />}
    </div>
  );
}

function EditRoleModal({ user, onClose, onSave }) {
  const [role, setRole] = useStateA(user.role);
  return (
    <Modal title="Edit role" subtitle={user.name + " · " + user.email} icon="key" onClose={onClose}>
      <div className="p-5 space-y-2">
        {Object.values(ROLES).map(r => {
          const on = role === r.key;
          return (
            <button key={r.key} onClick={() => setRole(r.key)}
              className={`w-full text-left rounded-lg border px-3.5 py-3 flex items-start gap-3 transition-all ${on ? "border-transparent ring-2" : "border-zinc-200 hover:bg-zinc-50"}`}
              style={on ? { boxShadow: "0 0 0 2px " + r.color, background: r.color + "0a" } : undefined}>
              <span className="mt-0.5 w-4 h-4 rounded-full border-2 flex items-center justify-center shrink-0" style={{ borderColor: on ? r.color : "#d4d4d8" }}>{on && <span className="w-2 h-2 rounded-full" style={{ background: r.color }} />}</span>
              <div>
                <div className="text-[13.5px] font-semibold text-zinc-800">{r.label}</div>
                <div className="text-[12px] text-zinc-500 mt-0.5">{r.desc}</div>
              </div>
            </button>
          );
        })}
      </div>
      <div className="flex items-center justify-end gap-2 px-5 py-3.5 border-t border-zinc-100 bg-zinc-50/50">
        <Button variant="default" size="md" onClick={onClose}>Cancel</Button>
        <Button variant="primary" size="md" icon="check" onClick={() => onSave(user.id, role)}>Save changes</Button>
      </div>
    </Modal>
  );
}

function InviteModal({ onClose, onInvite }) {
  const [email, setEmail] = useStateA("");
  const [name, setName] = useStateA("");
  const [role, setRole] = useStateA("ops_staff");
  const [dept, setDept] = useStateA("Operations");
  const [busy, setBusy] = useStateA(false);
  const valid = /\S+@\S+\.\S+/.test(email) && name.trim().length > 1;

  async function send() {
    setBusy(true);
    await onInvite(email, name.trim(), role, dept.trim() || "Operations");
    setBusy(false);
  }

  return (
    <Modal title="Invite a user" subtitle="They'll receive an email to set their password." icon="plus" onClose={onClose}>
      <div className="p-5 space-y-4">
        <label className="block">
          <span className="text-[12.5px] font-medium text-zinc-700">Full name</span>
          <input value={name} onChange={e => setName(e.target.value)} placeholder="Ahmad Razif" autoFocus
            className="mt-1.5 w-full h-10 px-3 rounded-lg border border-zinc-300 outline-none focus:border-zinc-900 text-[13.5px] text-zinc-800" />
        </label>
        <label className="block">
          <span className="text-[12.5px] font-medium text-zinc-700">Work email</span>
          <input type="email" value={email} onChange={e => setEmail(e.target.value)} placeholder="name@trapo.co"
            className="mt-1.5 w-full h-10 px-3 rounded-lg border border-zinc-300 outline-none focus:border-zinc-900 text-[13.5px] text-zinc-800" />
        </label>
        <label className="block">
          <span className="text-[12.5px] font-medium text-zinc-700">Department</span>
          <input value={dept} onChange={e => setDept(e.target.value)} placeholder="Fulfillment"
            className="mt-1.5 w-full h-10 px-3 rounded-lg border border-zinc-300 outline-none focus:border-zinc-900 text-[13.5px] text-zinc-800" />
        </label>
        <label className="block">
          <span className="text-[12.5px] font-medium text-zinc-700">Assign role</span>
          <div className="mt-1.5 grid grid-cols-2 gap-2">
            {Object.values(ROLES).map(r => {
              const on = role === r.key;
              return (
                <button key={r.key} onClick={() => setRole(r.key)} className={`rounded-lg border px-3 py-2 text-left transition-all ${on ? "border-transparent ring-2" : "border-zinc-200 hover:bg-zinc-50"}`} style={on ? { boxShadow: "0 0 0 2px " + r.color, background: r.color + "0a" } : undefined}>
                  <div className="flex items-center gap-1.5"><span className="w-1.5 h-1.5 rounded-full" style={{ background: r.color }} /><span className="text-[12.5px] font-semibold text-zinc-800">{r.label}</span></div>
                  <div className="text-[11px] text-zinc-400 mt-0.5">{ROLES[r.key].desc}</div>
                </button>
              );
            })}
          </div>
        </label>
      </div>
      <div className="flex items-center justify-end gap-2 px-5 py-3.5 border-t border-zinc-100 bg-zinc-50/50">
        <Button variant="default" size="md" onClick={onClose}>Cancel</Button>
        <Button variant="primary" size="md" icon={busy ? "refresh" : "send"} disabled={!valid || busy} onClick={send}>
          {busy ? "Sending…" : "Send invite"}
        </Button>
      </div>
    </Modal>
  );
}

/* ---------- Integrations page ---------- */
function IntegrationsPage({ canManage, onToast }) {
  const [integ, setInteg] = useStateA(INTEGRATIONS);
  function reconnect(i) {
    setInteg(xs => xs.map(x => x.id === i.id ? { ...x, status: "connected", sync: "Synced just now", color: "#16a34a" } : x));
    onToast(`${i.name} reconnected`, { icon: "plug" });
  }
  function disconnect(i) {
    setInteg(xs => xs.map(x => x.id === i.id ? { ...x, status: "disconnected", sync: "Not connected", color: "#71717a" } : x));
    onToast(`${i.name} disconnected`, { tone: "warn", icon: "plug" });
  }
  return (
    <div className="p-6 max-w-[900px]">
      <div className="mb-4">
        <h2 className="text-[15px] font-semibold text-zinc-900 tracking-tight">Integrations</h2>
        <p className="text-[12.5px] text-zinc-500 mt-0.5">Connected systems feeding the exception engine. {integ.filter(i=>i.status==="connected").length} of {integ.length} healthy.</p>
      </div>
      <div className="grid sm:grid-cols-2 gap-3.5">
        {integ.map(i => {
          const s = INTEG_STATUS[i.status];
          return (
            <div key={i.id} className="bg-white rounded-xl border border-zinc-200 p-4">
              <div className="flex items-start gap-3">
                <div className="flex items-center justify-center w-10 h-10 rounded-lg text-white font-bold text-[13px] shrink-0" style={{ background: i.color }}>{i.letter}</div>
                <div className="min-w-0 flex-1">
                  <div className="flex items-center gap-2">
                    <h3 className="text-[13.5px] font-semibold text-zinc-800">{i.name}</h3>
                    <Tag>{i.cat}</Tag>
                  </div>
                  <p className="text-[12px] text-zinc-500 mt-1 leading-snug">{i.desc}</p>
                </div>
              </div>
              <div className="flex items-center justify-between mt-3.5 pt-3 border-t border-zinc-100">
                <span className="inline-flex items-center gap-1.5 text-[12px] font-medium" style={{ color: s.color }}>
                  <span className="w-1.5 h-1.5 rounded-full" style={{ background: s.dot }} />{s.label} · <span className="text-zinc-400 font-normal">{i.sync}</span>
                </span>
                {canManage ? (
                  i.status === "connected"
                    ? <button onClick={() => disconnect(i)} className="text-[12px] font-medium text-zinc-500 hover:text-zinc-800">Disconnect</button>
                    : <button onClick={() => reconnect(i)} className="text-[12px] font-semibold" style={{ color: "var(--accent-ink)" }}>{i.status === "error" ? "Fix connection" : "Connect"}</button>
                ) : <Icon name={i.status === "connected" ? "check" : "alert"} size={15} className="text-zinc-300" />}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ---------- Department Permissions page ---------- */
const DEPT_LIST = [
  "Fulfillment", "Warranty", "Logistics", "Customer Experience",
  "Installations", "Operations", "Finance", "IT / Admin",
];
const DEPT_FEAT = [
  { key: "active",          label: "Access",        icon: "power",    desc: "Dept can log in and use the system" },
  { key: "view_exceptions", label: "Exceptions",    icon: "alert",    desc: "View and work on exception queue" },
  { key: "import_orders",   label: "Import Orders", icon: "download", desc: "Shopify order import" },
  { key: "automations",     label: "Automations",   icon: "zap",      desc: "Workflow builder & resolution agents" },
  { key: "analytics",       label: "Analytics",     icon: "barchart", desc: "View reports and analytics" },
  { key: "audit_logs",      label: "Audit Logs",    icon: "list",     desc: "Read audit trail" },
  { key: "warranty",        label: "Warranty",      icon: "shield",   desc: "Access warranty claims" },
  { key: "installations",   label: "Installations", icon: "wrench",   desc: "Access installation jobs" },
];
const DEFAULT_DEPT_PERMS = {
  "Fulfillment":         { active:true, view_exceptions:true,  import_orders:true,  automations:false, analytics:false, audit_logs:false, warranty:false, installations:false },
  "Warranty":            { active:true, view_exceptions:true,  import_orders:false, automations:false, analytics:false, audit_logs:false, warranty:true,  installations:false },
  "Logistics":           { active:true, view_exceptions:true,  import_orders:false, automations:false, analytics:false, audit_logs:false, warranty:false, installations:false },
  "Customer Experience": { active:true, view_exceptions:true,  import_orders:false, automations:false, analytics:true,  audit_logs:false, warranty:true,  installations:false },
  "Installations":       { active:true, view_exceptions:true,  import_orders:false, automations:false, analytics:false, audit_logs:false, warranty:false, installations:true  },
  "Operations":          { active:true, view_exceptions:true,  import_orders:true,  automations:true,  analytics:true,  audit_logs:true,  warranty:true,  installations:true  },
  "Finance":             { active:true, view_exceptions:false, import_orders:false, automations:false, analytics:true,  audit_logs:false, warranty:false, installations:false },
  "IT / Admin":          { active:true, view_exceptions:true,  import_orders:true,  automations:true,  analytics:true,  audit_logs:true,  warranty:true,  installations:true  },
};

function Toggle({ on, onChange, disabled }) {
  return (
    <button onClick={onChange} disabled={disabled}
      className={`relative inline-flex items-center w-9 h-5 rounded-full transition-colors focus:outline-none ${on ? "bg-teal-500" : "bg-zinc-200"} ${disabled ? "opacity-40 cursor-not-allowed" : "cursor-pointer"}`}>
      <span className={`absolute w-3.5 h-3.5 rounded-full bg-white shadow transition-transform ${on ? "translate-x-[18px]" : "translate-x-[3px]"}`} />
    </button>
  );
}

function DeptPermissionsPage({ onToast }) {
  const [perms, setPerms] = useStateA({ ...DEFAULT_DEPT_PERMS });
  const [saving, setSaving] = useStateA({});
  const [addDept, setAddDept] = useStateA("");
  const [showAdd, setShowAdd] = useStateA(false);
  const [renamingDept, setRenamingDept] = useStateA(null);   // dept name being renamed
  const [renameVal, setRenameVal] = useStateA("");
  const [confirmDelete, setConfirmDelete] = useStateA(null); // dept name pending delete

  React.useEffect(() => {
    sb.from("dept_permissions").select("*").then(({ data }) => {
      if (data && data.length > 0) {
        const map = {};
        data.forEach(({ dept, updated_at, ...rest }) => { map[dept] = rest; });
        setPerms(prev => ({ ...prev, ...map }));
      }
    });
  }, []);

  const depts = Object.keys(perms);

  async function toggle(dept, key) {
    const prev = perms[dept]?.[key] ?? false;
    const newDeptPerms = { ...perms[dept], [key]: !prev };
    setPerms(p => ({ ...p, [dept]: newDeptPerms }));
    setSaving(s => ({ ...s, [`${dept}-${key}`]: true }));
    const { error } = await sb.from("dept_permissions")
      .upsert({ dept, ...newDeptPerms, updated_at: new Date().toISOString() }, { onConflict: "dept" });
    setSaving(s => { const n = {...s}; delete n[`${dept}-${key}`]; return n; });
    if (error) {
      setPerms(p => ({ ...p, [dept]: { ...newDeptPerms, [key]: prev } }));
      onToast("Failed to save", { tone: "danger", icon: "alert" });
    }
  }

  async function addDepartment() {
    const d = addDept.trim();
    if (!d || perms[d]) return;
    const defaults = { active:true, view_exceptions:true, import_orders:false, automations:false, analytics:false, audit_logs:false, warranty:false, installations:false };
    setPerms(p => ({ ...p, [d]: defaults }));
    setAddDept(""); setShowAdd(false);
    const { error } = await sb.from("dept_permissions")
      .upsert({ dept: d, ...defaults, updated_at: new Date().toISOString() }, { onConflict: "dept" });
    if (error) { onToast("Failed to add department", { tone: "danger", icon: "alert" }); return; }
    onToast(`Department "${d}" added`, { icon: "check" });
  }

  function startRename(dept) {
    setRenamingDept(dept);
    setRenameVal(dept);
  }

  async function commitRename() {
    const newName = renameVal.trim();
    if (!newName || newName === renamingDept) { setRenamingDept(null); return; }
    if (perms[newName]) { onToast("A department with that name already exists", { tone: "warn", icon: "alert" }); return; }

    const oldPerms = perms[renamingDept];
    // optimistic update
    setPerms(p => {
      const next = { ...p };
      delete next[renamingDept];
      next[newName] = oldPerms;
      return next;
    });
    setRenamingDept(null);

    // in Supabase: insert new row + delete old (primary key is dept text, can't UPDATE pk)
    const { error: insErr } = await sb.from("dept_permissions")
      .upsert({ dept: newName, ...oldPerms, updated_at: new Date().toISOString() }, { onConflict: "dept" });
    if (insErr) {
      // revert
      setPerms(p => { const next = { ...p }; delete next[newName]; next[renamingDept] = oldPerms; return next; });
      onToast("Failed to rename department", { tone: "danger", icon: "alert" }); return;
    }
    await sb.from("dept_permissions").delete().eq("dept", renamingDept);
    onToast(`Renamed to "${newName}"`, { icon: "check" });
  }

  async function deleteDepartment(dept) {
    setConfirmDelete(null);
    setPerms(p => { const next = { ...p }; delete next[dept]; return next; });
    const { error } = await sb.from("dept_permissions").delete().eq("dept", dept);
    if (error) {
      setPerms(p => ({ ...p, [dept]: perms[dept] }));
      onToast("Failed to delete department", { tone: "danger", icon: "alert" }); return;
    }
    onToast(`"${dept}" deleted`, { tone: "warn", icon: "trash" });
  }

  return (
    <div className="p-6">
      <div className="flex items-start justify-between mb-5 flex-wrap gap-3">
        <div>
          <h2 className="text-[15px] font-semibold text-zinc-900 tracking-tight">Department Permissions</h2>
          <p className="text-[12.5px] text-zinc-500 mt-0.5">Toggle feature access per department. Double-click name to rename.</p>
        </div>
        <Button variant="default" size="md" icon="plus" onClick={() => setShowAdd(s => !s)}>Add Department</Button>
      </div>

      {showAdd && (
        <div className="mb-4 flex items-center gap-2 p-3.5 bg-white border border-zinc-200 rounded-xl max-w-sm">
          <input value={addDept} onChange={e => setAddDept(e.target.value)} onKeyDown={e => { if (e.key === "Enter") addDepartment(); if (e.key === "Escape") setShowAdd(false); }}
            placeholder="Department name…" autoFocus
            className="flex-1 h-9 px-3 rounded-lg border border-zinc-300 outline-none focus:border-zinc-900 text-[13px] text-zinc-800" />
          <Button variant="primary" size="md" onClick={addDepartment} disabled={!addDept.trim()}>Add</Button>
          <button onClick={() => setShowAdd(false)} className="w-8 h-8 rounded-lg flex items-center justify-center text-zinc-400 hover:bg-zinc-100"><Icon name="x" size={16} /></button>
        </div>
      )}

      {/* Legend */}
      <div className="flex flex-wrap gap-x-5 gap-y-1.5 mb-4">
        {DEPT_FEAT.map(f => (
          <span key={f.key} className="flex items-center gap-1.5 text-[11.5px] text-zinc-500">
            <Icon name={f.icon} size={13} className="text-zinc-400" />{f.label}
            <span className="text-zinc-300">—</span>
            <span className="text-zinc-400">{f.desc}</span>
          </span>
        ))}
      </div>

      {/* Matrix */}
      <div className="bg-white rounded-xl border border-zinc-200 overflow-x-auto">
        <table className="w-full border-collapse min-w-[860px]">
          <thead>
            <tr className="border-b border-zinc-100">
              <th className="text-left px-5 py-3 text-[11px] font-semibold uppercase tracking-wider text-zinc-400 w-52 whitespace-nowrap">Department</th>
              {DEPT_FEAT.map(f => (
                <th key={f.key} className="px-4 py-3 text-center">
                  <div className="flex flex-col items-center gap-1">
                    <Icon name={f.icon} size={14} className="text-zinc-400" />
                    <span className="text-[10.5px] font-semibold uppercase tracking-wider text-zinc-400 whitespace-nowrap">{f.label}</span>
                  </div>
                </th>
              ))}
              <th className="w-16" />
            </tr>
          </thead>
          <tbody>
            {depts.map((dept, di) => {
              const dp = perms[dept] || {};
              const isActive = dp.active !== false;
              const isRenaming = renamingDept === dept;
              return (
                <tr key={dept} className={`border-b border-zinc-100 last:border-0 transition-colors hover:bg-zinc-50 group ${!isActive ? "opacity-50" : ""}`}>
                  <td className="px-5 py-3">
                    <div className="flex items-center gap-2">
                      <span className="flex items-center justify-center w-7 h-7 rounded-lg text-[11px] font-bold text-white shrink-0"
                        style={{ background: `hsl(${(di * 47) % 360}, 55%, 50%)` }}>
                        {dept.slice(0, 2).toUpperCase()}
                      </span>
                      {isRenaming ? (
                        <input autoFocus value={renameVal} onChange={e => setRenameVal(e.target.value)}
                          onBlur={commitRename}
                          onKeyDown={e => { if (e.key === "Enter") commitRename(); if (e.key === "Escape") setRenamingDept(null); }}
                          className="flex-1 h-7 px-2 rounded-md border border-zinc-300 outline-none focus:border-teal-500 text-[13px] text-zinc-800 min-w-0" />
                      ) : (
                        <span onDoubleClick={() => startRename(dept)} title="Double-click to rename"
                          className="text-[13px] font-medium text-zinc-800 whitespace-nowrap cursor-text select-none">
                          {dept}
                        </span>
                      )}
                    </div>
                  </td>
                  {DEPT_FEAT.map(f => (
                    <td key={f.key} className="px-4 py-3 text-center">
                      <div className="flex justify-center">
                        {saving[`${dept}-${f.key}`]
                          ? <Icon name="refresh" size={16} className="animate-spin text-zinc-300" />
                          : <Toggle on={!!dp[f.key]} onChange={() => toggle(dept, f.key)} disabled={f.key !== "active" && !isActive} />
                        }
                      </div>
                    </td>
                  ))}
                  <td className="pr-4 py-3 text-right">
                    <div className="flex items-center justify-end gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
                      <button onClick={() => startRename(dept)} title="Rename"
                        className="w-7 h-7 rounded-md flex items-center justify-center text-zinc-400 hover:bg-zinc-100 hover:text-zinc-700">
                        <Icon name="edit" size={13} />
                      </button>
                      <button onClick={() => setConfirmDelete(dept)} title="Delete"
                        className="w-7 h-7 rounded-md flex items-center justify-center text-zinc-400 hover:bg-red-50 hover:text-red-600">
                        <Icon name="trash" size={13} />
                      </button>
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      <p className="mt-3 text-[11.5px] text-zinc-400 flex items-center gap-1.5">
        <Icon name="info" size={13} />
        Department permissions layer on top of role-based access. A user still needs the right role to use a feature.
      </p>

      {/* Delete confirmation modal */}
      {confirmDelete && (
        <Modal title="Delete department?" subtitle={`"${confirmDelete}" and all its permission settings will be permanently removed.`} icon="trash" onClose={() => setConfirmDelete(null)}>
          <div className="px-5 py-4 bg-red-50/60 border-b border-zinc-100">
            <p className="text-[13px] text-zinc-600">This does <strong>not</strong> remove users assigned to this department — their accounts remain active.</p>
          </div>
          <div className="flex items-center justify-end gap-2 px-5 py-3.5 bg-zinc-50/50">
            <Button variant="default" size="md" onClick={() => setConfirmDelete(null)}>Cancel</Button>
            <button onClick={() => deleteDepartment(confirmDelete)}
              className="inline-flex items-center gap-1.5 px-4 h-9 rounded-lg text-[13px] font-semibold text-white bg-red-600 hover:bg-red-700 active:bg-red-800 transition-colors">
              <Icon name="trash" size={14} /> Delete
            </button>
          </div>
        </Modal>
      )}
    </div>
  );
}

Object.assign(window, { Modal, UsersPage, IntegrationsPage, RoleBadge, EditRoleModal, InviteModal, DeptPermissionsPage });
