/**
 * User Management — Admin module for managing users, invitations, and activity
 * Design: Warm Showroom palette, tabbed layout
 */
import { useState, useMemo, useCallback } from "react";
import { useAuth } from "@/_core/hooks/useAuth";
import { trpc } from "@/lib/trpc";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { toast } from "sonner";
import {
  Users, Shield, Headphones, User, Search, Trash2,
  CheckCircle2, AlertTriangle, Crown, Mail, Send,
  Clock, XCircle, RefreshCw, Download, History,
  MoreHorizontal, UserPlus, CheckSquare, Square,
  ArrowUpDown, Eye, Copy, ExternalLink, Pencil, Link2Off,
} from "lucide-react";

/* ─── Role config ─── */
const ROLE_CONFIG: Record<string, {
  icon: React.ReactNode;
  color: string;
  bg: string;
  label: string;
  description: string;
}> = {
  admin: {
    icon: <Crown className="w-3.5 h-3.5" />,
    color: "#14532D",
    bg: "#14532D18",
    label: "Admin",
    description: "Full access: conversations, workflow designer, user management",
  },
  agent: {
    icon: <Headphones className="w-3.5 h-3.5" />,
    color: "#0369a1",
    bg: "#0369a118",
    label: "Agent",
    description: "Can view and reply to conversations in the agent dashboard",
  },
  user: {
    icon: <User className="w-3.5 h-3.5" />,
    color: "#78716C",
    bg: "#78716C18",
    label: "User",
    description: "Basic access only, no dashboard or workflow access",
  },
};

const INVITE_STATUS_CONFIG: Record<string, { color: string; bg: string; icon: React.ReactNode; label: string }> = {
  pending: { color: "#d97706", bg: "#d9770618", icon: <Clock className="w-3 h-3" />, label: "Pending" },
  accepted: { color: "#16a34a", bg: "#16a34a18", icon: <CheckCircle2 className="w-3 h-3" />, label: "Accepted" },
  expired: { color: "#78716C", bg: "#78716C18", icon: <Clock className="w-3 h-3" />, label: "Expired" },
  revoked: { color: "#dc2626", bg: "#dc262618", icon: <XCircle className="w-3 h-3" />, label: "Revoked" },
};

const AUDIT_ACTION_LABELS: Record<string, { label: string; color: string }> = {
  role_change: { label: "Role Changed", color: "#0369a1" },
  user_deleted: { label: "User Deleted", color: "#dc2626" },
  bulk_role_change: { label: "Bulk Role Change", color: "#7c3aed" },
  bulk_delete: { label: "Bulk Delete", color: "#dc2626" },
  invitation_sent: { label: "Invitation Sent", color: "#16a34a" },
  invitation_resent: { label: "Invitation Resent", color: "#d97706" },
  invitation_revoked: { label: "Invitation Revoked", color: "#dc2626" },
  invitation_accepted: { label: "Invitation Accepted", color: "#16a34a" },
};

/* ─── Role Badge ─── */
function RoleBadge({ role }: { role: string }) {
  const config = ROLE_CONFIG[role] || ROLE_CONFIG.user;
  return (
    <span
      className="inline-flex items-center gap-1.5 text-xs font-medium px-2.5 py-1 rounded-full"
      style={{ background: config.bg, color: config.color }}
    >
      {config.icon}
      {config.label}
    </span>
  );
}

function InviteStatusBadge({ status }: { status: string }) {
  const config = INVITE_STATUS_CONFIG[status] || INVITE_STATUS_CONFIG.pending;
  return (
    <span
      className="inline-flex items-center gap-1 text-xs font-medium px-2.5 py-1 rounded-full"
      style={{ background: config.bg, color: config.color }}
    >
      {config.icon}
      {config.label}
    </span>
  );
}

/* ─── Stats Cards ─── */
function RoleStats({ users, invitations }: { users: any[]; invitations: any[] }) {
  const counts = useMemo(() => {
    const c = { total: users.length, admin: 0, agent: 0, user: 0, pendingInvites: 0 };
    users.forEach(u => {
      if (u.role in c) c[u.role as keyof typeof c]++;
    });
    c.pendingInvites = invitations.filter(i => i.status === "pending").length;
    return c;
  }, [users, invitations]);

  const stats = [
    { label: "Total Users", value: counts.total, icon: <Users className="w-5 h-5" />, iconBg: "#14532D14", iconColor: "#14532D" },
    { label: "Admins", value: counts.admin, icon: <Crown className="w-5 h-5" />, iconBg: "#14532D18", iconColor: "#14532D" },
    { label: "Agents", value: counts.agent, icon: <Headphones className="w-5 h-5" />, iconBg: "#0369a118", iconColor: "#0369a1" },
    { label: "Pending Invites", value: counts.pendingInvites, icon: <Mail className="w-5 h-5" />, iconBg: "#d9770618", iconColor: "#d97706" },
  ];

  return (
    <div className="grid grid-cols-2 lg:grid-cols-4 gap-3">
      {stats.map(s => (
        <div key={s.label} className="p-4 rounded-xl border" style={{ background: "#fff", borderColor: "#e7e0d5" }}>
          <div className="flex items-center gap-3">
            <div className="w-10 h-10 rounded-lg flex items-center justify-center" style={{ background: s.iconBg, color: s.iconColor }}>
              {s.icon}
            </div>
            <div>
              <div className="text-2xl font-bold" style={{ color: "#292524", fontFamily: "'Playfair Display', serif" }}>{s.value}</div>
              <div className="text-xs" style={{ color: "#a8a29e", fontFamily: "'Source Sans 3', sans-serif" }}>{s.label}</div>
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

/* ─── Send Invitation Dialog ─── */
function SendInviteDialog({ open, onOpenChange }: { open: boolean; onOpenChange: (open: boolean) => void }) {
  const [email, setEmail] = useState("");
  const [role, setRole] = useState<string>("agent");
  const [message, setMessage] = useState("");
  const utils = trpc.useUtils();

  const sendMutation = trpc.invitations.send.useMutation({
    onSuccess: (data) => {
      toast.success("Invitation sent!", {
        description: `Invitation sent to ${data.email} as ${ROLE_CONFIG[data.role]?.label || data.role}.`,
      });
      utils.invitations.list.invalidate();
      utils.auditLogs.list.invalidate();
      setEmail("");
      setRole("agent");
      setMessage("");
      onOpenChange(false);
    },
    onError: (error) => {
      toast.error("Failed to send invitation", { description: error.message });
    },
  });

  const handleSend = () => {
    if (!email.trim()) { toast.error("Email is required"); return; }
    sendMutation.mutate({ email: email.trim(), role: role as "user" | "agent" | "admin", message: message.trim() || undefined });
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent style={{ borderColor: "#e7e0d5" }}>
        <DialogHeader>
          <DialogTitle style={{ fontFamily: "'Playfair Display', serif", color: "#292524" }}>
            Send Invitation
          </DialogTitle>
          <DialogDescription style={{ fontFamily: "'Source Sans 3', sans-serif" }}>
            Invite a new team member to join the Homelegance chatbot system. They will receive a link to accept the invitation.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4 py-2">
          <div>
            <label className="text-sm font-medium block mb-1.5" style={{ color: "#292524", fontFamily: "'Source Sans 3', sans-serif" }}>
              Email Address *
            </label>
            <input
              type="email"
              placeholder="colleague@homelegance.com"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              className="w-full px-3 py-2.5 rounded-xl border text-sm"
              style={{ borderColor: "#e7e0d5", background: "#fff", fontFamily: "'Source Sans 3', sans-serif", color: "#292524" }}
            />
          </div>

          <div>
            <label className="text-sm font-medium block mb-1.5" style={{ color: "#292524", fontFamily: "'Source Sans 3', sans-serif" }}>
              Role
            </label>
            <Select value={role} onValueChange={setRole}>
              <SelectTrigger style={{ borderColor: "#e7e0d5", background: "#fff" }}>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="admin">
                  <div className="flex items-center gap-2">
                    <Crown className="w-3.5 h-3.5" style={{ color: "#14532D" }} />
                    <span>Admin — Full access</span>
                  </div>
                </SelectItem>
                <SelectItem value="agent">
                  <div className="flex items-center gap-2">
                    <Headphones className="w-3.5 h-3.5" style={{ color: "#0369a1" }} />
                    <span>Agent — Dashboard access</span>
                  </div>
                </SelectItem>
                <SelectItem value="user">
                  <div className="flex items-center gap-2">
                    <User className="w-3.5 h-3.5" style={{ color: "#78716C" }} />
                    <span>User — Basic access</span>
                  </div>
                </SelectItem>
              </SelectContent>
            </Select>
          </div>

          <div>
            <label className="text-sm font-medium block mb-1.5" style={{ color: "#292524", fontFamily: "'Source Sans 3', sans-serif" }}>
              Personal Message (optional)
            </label>
            <textarea
              placeholder="Welcome to the team! We'd love to have you help manage our chatbot..."
              value={message}
              onChange={(e) => setMessage(e.target.value)}
              rows={3}
              className="w-full px-3 py-2.5 rounded-xl border text-sm resize-none"
              style={{ borderColor: "#e7e0d5", background: "#fff", fontFamily: "'Source Sans 3', sans-serif", color: "#292524" }}
            />
          </div>

          <div className="p-3 rounded-lg" style={{ background: "#14532D08", border: "1px solid #14532D18" }}>
            <p className="text-xs" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>
              The invitation link will be valid for <strong>7 days</strong>. The invitee will need to sign in to accept the invitation and receive their assigned role.
            </p>
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} style={{ borderColor: "#e7e0d5" }}>
            Cancel
          </Button>
          <Button
            onClick={handleSend}
            disabled={sendMutation.isPending || !email.trim()}
            className="text-white"
            style={{ background: "#14532D" }}
          >
            {sendMutation.isPending ? (
              <><RefreshCw className="w-4 h-4 animate-spin mr-2" /> Sending...</>
            ) : (
              <><Send className="w-4 h-4 mr-2" /> Send Invitation</>
            )}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

/* ─── Users Tab ─── */
function UsersTab() {
  const { user: currentUser } = useAuth();
  const [searchQuery, setSearchQuery] = useState("");
  const [roleFilter, setRoleFilter] = useState<string>("all");
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());
  const [confirmDialog, setConfirmDialog] = useState<{
    open: boolean; type: "role" | "delete" | "bulkRole" | "bulkDelete";
    userId?: number; userName?: string; currentRole?: string; newRole?: string;
  }>({ open: false, type: "role" });
  const [erpEditState, setErpEditState] = useState<{
    userId: number | null; value: string;
  }>({ userId: null, value: "" });

  const utils = trpc.useUtils();
  const { data: usersList, isLoading } = trpc.users.list.useQuery();

  const updateRoleMutation = trpc.users.updateRole.useMutation({
    onSuccess: (data) => {
      toast.success(`Role updated to ${ROLE_CONFIG[data.role]?.label || data.role}`);
      utils.users.list.invalidate();
      utils.auditLogs.list.invalidate();
      setConfirmDialog(prev => ({ ...prev, open: false }));
    },
    onError: (error) => toast.error("Failed to update role", { description: error.message }),
  });

  const deleteMutation = trpc.users.delete.useMutation({
    onSuccess: () => {
      toast.success("User deleted successfully");
      utils.users.list.invalidate();
      utils.auditLogs.list.invalidate();
      setConfirmDialog(prev => ({ ...prev, open: false }));
    },
    onError: (error) => toast.error("Failed to delete user", { description: error.message }),
  });

  const bulkRoleMutation = trpc.users.bulkUpdateRole.useMutation({
    onSuccess: (results) => {
      const successes = results.filter(r => r.success).length;
      toast.success(`${successes} user(s) updated`);
      utils.users.list.invalidate();
      utils.auditLogs.list.invalidate();
      setSelectedIds(new Set());
      setConfirmDialog(prev => ({ ...prev, open: false }));
    },
    onError: (error) => toast.error("Bulk update failed", { description: error.message }),
  });

  const bulkDeleteMutation = trpc.users.bulkDelete.useMutation({
    onSuccess: (results) => {
      const successes = results.filter(r => r.success).length;
      toast.success(`${successes} user(s) deleted`);
      utils.users.list.invalidate();
      utils.auditLogs.list.invalidate();
      setSelectedIds(new Set());
      setConfirmDialog(prev => ({ ...prev, open: false }));
    },
    onError: (error) => toast.error("Bulk delete failed", { description: error.message }),
  });

  const updateErpCidMutation = trpc.users.updateErpContactCid.useMutation({
    onSuccess: () => {
      toast.success("ERP Contact ID updated");
      utils.users.list.invalidate();
      setErpEditState({ userId: null, value: "" });
    },
    onError: (error) => toast.error("Failed to update ERP Contact ID", { description: error.message }),
  });

  const exportCsvQuery = trpc.users.exportCsv.useQuery(undefined, { enabled: false });

  const filteredUsers = useMemo(() => {
    if (!usersList) return [];
    return usersList.filter((u: any) => {
      const matchesSearch = !searchQuery ||
        u.name?.toLowerCase().includes(searchQuery.toLowerCase()) ||
        u.email?.toLowerCase().includes(searchQuery.toLowerCase());
      const matchesRole = roleFilter === "all" || u.role === roleFilter;
      return matchesSearch && matchesRole;
    });
  }, [usersList, searchQuery, roleFilter]);

  const toggleSelect = (id: number) => {
    setSelectedIds(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  };

  const toggleSelectAll = () => {
    if (selectedIds.size === filteredUsers.filter((u: any) => u.id !== currentUser?.id).length) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(filteredUsers.filter((u: any) => u.id !== currentUser?.id).map((u: any) => u.id)));
    }
  };

  const handleExportCsv = async () => {
    const result = await exportCsvQuery.refetch();
    if (result.data) {
      const blob = new Blob([result.data.csv], { type: "text/csv" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `homelegance-users-${new Date().toISOString().split("T")[0]}.csv`;
      a.click();
      URL.revokeObjectURL(url);
      toast.success(`Exported ${result.data.count} users`);
    }
  };

  const confirmAction = () => {
    const d = confirmDialog;
    if (d.type === "role" && d.userId && d.newRole) {
      updateRoleMutation.mutate({ userId: d.userId, role: d.newRole as "user" | "agent" | "admin" });
    } else if (d.type === "delete" && d.userId) {
      deleteMutation.mutate({ userId: d.userId });
    } else if (d.type === "bulkRole" && d.newRole) {
      bulkRoleMutation.mutate({ userIds: Array.from(selectedIds), role: d.newRole as "user" | "agent" | "admin" });
    } else if (d.type === "bulkDelete") {
      bulkDeleteMutation.mutate({ userIds: Array.from(selectedIds) });
    }
  };

  const isPending = updateRoleMutation.isPending || deleteMutation.isPending || bulkRoleMutation.isPending || bulkDeleteMutation.isPending;

  return (
    <div className="space-y-4">
      {/* Toolbar */}
      <div className="flex flex-col sm:flex-row gap-3">
        <div className="relative flex-1">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4" style={{ color: "#a8a29e" }} />
          <input
            type="text"
            placeholder="Search by name or email..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="w-full pl-10 pr-4 py-2.5 rounded-xl border text-sm"
            style={{ borderColor: "#e7e0d5", background: "#fff", fontFamily: "'Source Sans 3', sans-serif", color: "#292524" }}
          />
        </div>
        <Select value={roleFilter} onValueChange={setRoleFilter}>
          <SelectTrigger className="w-full sm:w-40" style={{ borderColor: "#e7e0d5", background: "#fff" }}>
            <SelectValue placeholder="Filter by role" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All Roles</SelectItem>
            <SelectItem value="admin">Admin</SelectItem>
            <SelectItem value="agent">Agent</SelectItem>
            <SelectItem value="user">User</SelectItem>
          </SelectContent>
        </Select>
        <Button variant="outline" onClick={handleExportCsv} className="gap-2" style={{ borderColor: "#e7e0d5" }}>
          <Download className="w-4 h-4" /> Export CSV
        </Button>
      </div>

      {/* Bulk Actions Bar */}
      {selectedIds.size > 0 && (
        <div className="flex items-center gap-3 p-3 rounded-xl border" style={{ background: "#14532D08", borderColor: "#14532D30" }}>
          <span className="text-sm font-medium" style={{ color: "#14532D" }}>
            {selectedIds.size} selected
          </span>
          <div className="flex gap-2 ml-auto">
            <Select onValueChange={(role) => setConfirmDialog({ open: true, type: "bulkRole", newRole: role })}>
              <SelectTrigger className="w-40 h-8 text-xs" style={{ borderColor: "#14532D30", background: "#fff" }}>
                <SelectValue placeholder="Change role to..." />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="admin">Admin</SelectItem>
                <SelectItem value="agent">Agent</SelectItem>
                <SelectItem value="user">User</SelectItem>
              </SelectContent>
            </Select>
            <Button
              variant="outline"
              size="sm"
              className="text-red-600 border-red-200 hover:bg-red-50"
              onClick={() => setConfirmDialog({ open: true, type: "bulkDelete" })}
            >
              <Trash2 className="w-3.5 h-3.5 mr-1" /> Delete
            </Button>
            <Button variant="ghost" size="sm" onClick={() => setSelectedIds(new Set())}>
              Clear
            </Button>
          </div>
        </div>
      )}

      {/* Users Table */}
      <div className="rounded-xl border overflow-hidden" style={{ background: "#fff", borderColor: "#e7e0d5" }}>
        <ScrollArea className="max-h-[500px]">
          <table className="w-full">
            <thead>
              <tr style={{ background: "#f5f0e8" }}>
                <th className="text-left px-3 py-3 w-10">
                  <button onClick={toggleSelectAll} className="flex items-center justify-center">
                    {selectedIds.size > 0 && selectedIds.size === filteredUsers.filter((u: any) => u.id !== currentUser?.id).length ? (
                      <CheckSquare className="w-4 h-4" style={{ color: "#14532D" }} />
                    ) : (
                      <Square className="w-4 h-4" style={{ color: "#a8a29e" }} />
                    )}
                  </button>
                </th>
                <th className="text-left text-xs font-semibold px-4 py-3" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>User</th>
                <th className="text-left text-xs font-semibold px-4 py-3" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>Role</th>
                <th className="text-left text-xs font-semibold px-4 py-3 hidden lg:table-cell" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>ERP Contact ID</th>
                <th className="text-left text-xs font-semibold px-4 py-3 hidden md:table-cell" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>Joined</th>
                <th className="text-left text-xs font-semibold px-4 py-3 hidden md:table-cell" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>Last Active</th>
                <th className="text-right text-xs font-semibold px-4 py-3" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>Actions</th>
              </tr>
            </thead>
            <tbody>
              {isLoading ? (
                <tr>
                  <td colSpan={7} className="text-center py-12">
                    <div className="animate-spin w-6 h-6 border-2 rounded-full mx-auto" style={{ borderColor: "#14532D", borderTopColor: "transparent" }} />
                    <p className="text-sm mt-2" style={{ color: "#a8a29e" }}>Loading users...</p>
                  </td>
                </tr>
              ) : filteredUsers.length === 0 ? (
                <tr>
                  <td colSpan={7} className="text-center py-12">
                    <Users className="w-8 h-8 mx-auto mb-2" style={{ color: "#d6d3d1" }} />
                    <p className="text-sm" style={{ color: "#a8a29e" }}>No users found</p>
                  </td>
                </tr>
              ) : (
                filteredUsers.map((u: any) => {
                  const isSelf = u.id === currentUser?.id;
                  const isSelected = selectedIds.has(u.id);
                  return (
                    <tr key={u.id} className="border-t transition-colors hover:bg-black/[0.02]" style={{ borderColor: "#e7e0d5", background: isSelected ? "#14532D06" : undefined }}>
                      <td className="px-3 py-3">
                        {isSelf ? (
                          <div className="w-4 h-4" />
                        ) : (
                          <button onClick={() => toggleSelect(u.id)} className="flex items-center justify-center">
                            {isSelected ? (
                              <CheckSquare className="w-4 h-4" style={{ color: "#14532D" }} />
                            ) : (
                              <Square className="w-4 h-4" style={{ color: "#d6d3d1" }} />
                            )}
                          </button>
                        )}
                      </td>
                      <td className="px-4 py-3">
                        <div className="flex items-center gap-3">
                          <div
                            className="w-9 h-9 rounded-full flex items-center justify-center shrink-0 text-xs font-medium"
                            style={{ background: ROLE_CONFIG[u.role]?.bg || "#78716C18", color: ROLE_CONFIG[u.role]?.color || "#78716C" }}
                          >
                            {u.name?.charAt(0).toUpperCase() || "?"}
                          </div>
                          <div>
                            <div className="flex items-center gap-2">
                              <span className="text-sm font-medium" style={{ color: "#292524", fontFamily: "'Source Sans 3', sans-serif" }}>
                                {u.name || "Unnamed"}
                              </span>
                              {isSelf && (
                                <span className="text-[10px] px-1.5 py-0.5 rounded-full font-medium" style={{ background: "#14532D14", color: "#14532D" }}>You</span>
                              )}
                            </div>
                            <span className="text-xs" style={{ color: "#a8a29e" }}>{u.email || "No email"}</span>
                          </div>
                        </div>
                      </td>
                      <td className="px-4 py-3"><RoleBadge role={u.role} /></td>
                      <td className="px-4 py-3 hidden lg:table-cell">
                        {erpEditState.userId === u.id ? (
                          <div className="flex items-center gap-1">
                            <input
                              type="text"
                              value={erpEditState.value}
                              onChange={(e) => setErpEditState(s => ({ ...s, value: e.target.value }))}
                              placeholder="e.g. C001234"
                              className="px-2 py-1 text-xs rounded border w-28"
                              style={{ borderColor: "#e7e0d5", fontFamily: "'Source Sans 3', sans-serif" }}
                              onKeyDown={(e) => {
                                if (e.key === "Enter") {
                                  updateErpCidMutation.mutate({ userId: u.id, erpContactCid: erpEditState.value.trim() || null });
                                } else if (e.key === "Escape") {
                                  setErpEditState({ userId: null, value: "" });
                                }
                              }}
                              autoFocus
                            />
                            <button
                              onClick={() => updateErpCidMutation.mutate({ userId: u.id, erpContactCid: erpEditState.value.trim() || null })}
                              disabled={updateErpCidMutation.isPending}
                              className="text-xs px-2 py-1 rounded text-white"
                              style={{ background: "#14532D" }}
                            >
                              Save
                            </button>
                            <button
                              onClick={() => setErpEditState({ userId: null, value: "" })}
                              className="text-xs px-2 py-1 rounded border"
                              style={{ borderColor: "#e7e0d5" }}
                            >
                              Cancel
                            </button>
                          </div>
                        ) : (
                          <div className="flex items-center gap-1.5 group">
                            <span className="text-xs font-mono" style={{ color: u.erpContactCid ? "#292524" : "#a8a29e" }}>
                              {u.erpContactCid || "—"}
                            </span>
                            {!isSelf && (
                              <button
                                onClick={() => setErpEditState({ userId: u.id, value: u.erpContactCid ?? "" })}
                                className="opacity-0 group-hover:opacity-100 transition-opacity"
                                title="Edit ERP Contact ID"
                              >
                                <Pencil className="w-3 h-3" style={{ color: "#78716C" }} />
                              </button>
                            )}
                          </div>
                        )}
                      </td>
                      <td className="px-4 py-3 hidden md:table-cell">
                        <span className="text-xs" style={{ color: "#78716C" }}>
                          {u.createdAt ? new Date(u.createdAt).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }) : "—"}
                        </span>
                      </td>
                      <td className="px-4 py-3 hidden md:table-cell">
                        <span className="text-xs" style={{ color: "#78716C" }}>
                          {u.lastSignedIn ? new Date(u.lastSignedIn).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }) : "Never"}
                        </span>
                      </td>
                      <td className="px-4 py-3 text-right">
                        {isSelf ? (
                          <span className="text-xs italic" style={{ color: "#a8a29e" }}>Cannot edit self</span>
                        ) : (
                          <div className="flex items-center gap-1 justify-end">
                            <Select
                              value={u.role}
                              onValueChange={(newRole) => setConfirmDialog({ open: true, type: "role", userId: u.id, userName: u.name || "this user", currentRole: u.role, newRole })}
                            >
                              <SelectTrigger className="w-28 h-8 text-xs" style={{ borderColor: "#e7e0d5" }}>
                                <SelectValue />
                              </SelectTrigger>
                              <SelectContent>
                                <SelectItem value="admin"><div className="flex items-center gap-2"><Crown className="w-3 h-3" style={{ color: "#14532D" }} /> Admin</div></SelectItem>
                                <SelectItem value="agent"><div className="flex items-center gap-2"><Headphones className="w-3 h-3" style={{ color: "#0369a1" }} /> Agent</div></SelectItem>
                                <SelectItem value="user"><div className="flex items-center gap-2"><User className="w-3 h-3" style={{ color: "#78716C" }} /> User</div></SelectItem>
                              </SelectContent>
                            </Select>
                            <Button
                              variant="ghost"
                              size="sm"
                              className="h-8 w-8 p-0 text-red-400 hover:text-red-600 hover:bg-red-50"
                              onClick={() => setConfirmDialog({ open: true, type: "delete", userId: u.id, userName: u.name || u.email || "this user" })}
                            >
                              <Trash2 className="w-3.5 h-3.5" />
                            </Button>
                          </div>
                        )}
                      </td>
                    </tr>
                  );
                })
              )}
            </tbody>
          </table>
        </ScrollArea>
      </div>

      {/* Confirmation Dialog */}
      <Dialog open={confirmDialog.open} onOpenChange={(open) => setConfirmDialog(prev => ({ ...prev, open }))}>
        <DialogContent style={{ borderColor: "#e7e0d5" }}>
          <DialogHeader>
            <DialogTitle style={{ fontFamily: "'Playfair Display', serif", color: "#292524" }}>
              {confirmDialog.type === "delete" ? "Delete User" :
               confirmDialog.type === "bulkDelete" ? `Delete ${selectedIds.size} Users` :
               confirmDialog.type === "bulkRole" ? `Change Role for ${selectedIds.size} Users` :
               "Confirm Role Change"}
            </DialogTitle>
            <DialogDescription style={{ fontFamily: "'Source Sans 3', sans-serif" }}>
              {confirmDialog.type === "delete" ? (
                <>Are you sure you want to delete <strong>{confirmDialog.userName}</strong>? This action cannot be undone.</>
              ) : confirmDialog.type === "bulkDelete" ? (
                <>Are you sure you want to delete <strong>{selectedIds.size} users</strong>? This action cannot be undone.</>
              ) : confirmDialog.type === "bulkRole" ? (
                <>Change the role of <strong>{selectedIds.size} users</strong> to <RoleBadge role={confirmDialog.newRole || "user"} />?</>
              ) : (
                <>Change the role for <strong>{confirmDialog.userName}</strong>.</>
              )}
            </DialogDescription>
          </DialogHeader>

          {confirmDialog.type === "role" && (
            <div className="space-y-3 py-2">
              <div className="flex items-center gap-3">
                <span className="text-sm" style={{ color: "#78716C", minWidth: 50 }}>From:</span>
                <RoleBadge role={confirmDialog.currentRole || "user"} />
              </div>
              <div className="flex items-center gap-3">
                <span className="text-sm" style={{ color: "#78716C", minWidth: 50 }}>To:</span>
                <RoleBadge role={confirmDialog.newRole || "user"} />
              </div>
            </div>
          )}

          {(confirmDialog.type === "delete" || confirmDialog.type === "bulkDelete") && (
            <div className="flex items-start gap-2 p-3 rounded-lg" style={{ background: "#dc262610", border: "1px solid #dc262630" }}>
              <AlertTriangle className="w-4 h-4 shrink-0 mt-0.5" style={{ color: "#dc2626" }} />
              <p className="text-xs" style={{ color: "#dc2626" }}>
                This will permanently remove the user(s) and their access. This cannot be undone.
              </p>
            </div>
          )}

          <DialogFooter>
            <Button variant="outline" onClick={() => setConfirmDialog(prev => ({ ...prev, open: false }))} style={{ borderColor: "#e7e0d5" }}>
              Cancel
            </Button>
            <Button
              onClick={confirmAction}
              disabled={isPending}
              className="text-white"
              style={{ background: confirmDialog.type === "delete" || confirmDialog.type === "bulkDelete" ? "#dc2626" : "#14532D" }}
            >
              {isPending ? "Processing..." : confirmDialog.type === "delete" || confirmDialog.type === "bulkDelete" ? "Delete" : "Confirm"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}

/* ─── Invitations Tab ─── */
function InvitationsTab() {
  const [statusFilter, setStatusFilter] = useState<string>("all");
  const utils = trpc.useUtils();
  const { data: invitationsList, isLoading } = trpc.invitations.list.useQuery();

  const resendMutation = trpc.invitations.resend.useMutation({
    onSuccess: () => {
      toast.success("Invitation resent with a new link");
      utils.invitations.list.invalidate();
      utils.auditLogs.list.invalidate();
    },
    onError: (error) => toast.error("Failed to resend", { description: error.message }),
  });

  const revokeMutation = trpc.invitations.revoke.useMutation({
    onSuccess: () => {
      toast.success("Invitation revoked");
      utils.invitations.list.invalidate();
      utils.auditLogs.list.invalidate();
    },
    onError: (error) => toast.error("Failed to revoke", { description: error.message }),
  });

  const filteredInvitations = useMemo(() => {
    if (!invitationsList) return [];
    if (statusFilter === "all") return invitationsList;
    return invitationsList.filter((i: any) => i.status === statusFilter);
  }, [invitationsList, statusFilter]);

  const copyInviteLink = (token: string) => {
    const base = import.meta.env.BASE_URL ?? "/";
    const link = `${window.location.origin}${base}invite/${token}`;
    navigator.clipboard.writeText(link);
    toast.success("Invite link copied to clipboard");
  };

  return (
    <div className="space-y-4">
      <div className="flex items-center gap-3">
        <Select value={statusFilter} onValueChange={setStatusFilter}>
          <SelectTrigger className="w-40" style={{ borderColor: "#e7e0d5", background: "#fff" }}>
            <SelectValue placeholder="Filter status" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All Status</SelectItem>
            <SelectItem value="pending">Pending</SelectItem>
            <SelectItem value="accepted">Accepted</SelectItem>
            <SelectItem value="expired">Expired</SelectItem>
            <SelectItem value="revoked">Revoked</SelectItem>
          </SelectContent>
        </Select>
        <span className="text-sm" style={{ color: "#a8a29e" }}>
          {filteredInvitations.length} invitation{filteredInvitations.length !== 1 ? "s" : ""}
        </span>
      </div>

      <div className="rounded-xl border overflow-hidden" style={{ background: "#fff", borderColor: "#e7e0d5" }}>
        <ScrollArea className="max-h-[500px]">
          <table className="w-full">
            <thead>
              <tr style={{ background: "#f5f0e8" }}>
                <th className="text-left text-xs font-semibold px-4 py-3" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>Email</th>
                <th className="text-left text-xs font-semibold px-4 py-3" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>Role</th>
                <th className="text-left text-xs font-semibold px-4 py-3" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>Status</th>
                <th className="text-left text-xs font-semibold px-4 py-3 hidden md:table-cell" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>Sent By</th>
                <th className="text-left text-xs font-semibold px-4 py-3 hidden md:table-cell" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>Expires</th>
                <th className="text-right text-xs font-semibold px-4 py-3" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>Actions</th>
              </tr>
            </thead>
            <tbody>
              {isLoading ? (
                <tr>
                  <td colSpan={6} className="text-center py-12">
                    <div className="animate-spin w-6 h-6 border-2 rounded-full mx-auto" style={{ borderColor: "#14532D", borderTopColor: "transparent" }} />
                    <p className="text-sm mt-2" style={{ color: "#a8a29e" }}>Loading invitations...</p>
                  </td>
                </tr>
              ) : filteredInvitations.length === 0 ? (
                <tr>
                  <td colSpan={6} className="text-center py-12">
                    <Mail className="w-8 h-8 mx-auto mb-2" style={{ color: "#d6d3d1" }} />
                    <p className="text-sm" style={{ color: "#a8a29e" }}>No invitations found</p>
                  </td>
                </tr>
              ) : (
                filteredInvitations.map((inv: any) => (
                  <tr key={inv.id} className="border-t transition-colors hover:bg-black/[0.02]" style={{ borderColor: "#e7e0d5" }}>
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-2">
                        <Mail className="w-4 h-4 shrink-0" style={{ color: "#a8a29e" }} />
                        <div>
                          <span className="text-sm font-medium block" style={{ color: "#292524", fontFamily: "'Source Sans 3', sans-serif" }}>
                            {inv.email}
                          </span>
                          {inv.message && (
                            <span className="text-xs block truncate max-w-[200px]" style={{ color: "#a8a29e" }}>
                              "{inv.message}"
                            </span>
                          )}
                        </div>
                      </div>
                    </td>
                    <td className="px-4 py-3"><RoleBadge role={inv.role} /></td>
                    <td className="px-4 py-3"><InviteStatusBadge status={inv.status} /></td>
                    <td className="px-4 py-3 hidden md:table-cell">
                      <span className="text-xs" style={{ color: "#78716C" }}>{inv.invitedByName || "—"}</span>
                    </td>
                    <td className="px-4 py-3 hidden md:table-cell">
                      <span className="text-xs" style={{ color: inv.status === "pending" && new Date(inv.expiresAt) < new Date() ? "#dc2626" : "#78716C" }}>
                        {inv.expiresAt ? new Date(inv.expiresAt).toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }) : "—"}
                      </span>
                    </td>
                    <td className="px-4 py-3 text-right">
                      <div className="flex items-center gap-1 justify-end">
                        {inv.status === "pending" && (
                          <>
                            <Button variant="ghost" size="sm" className="h-7 text-xs gap-1" onClick={() => copyInviteLink(inv.token)}>
                              <Copy className="w-3 h-3" /> Copy Link
                            </Button>
                            <Button
                              variant="ghost" size="sm" className="h-7 text-xs gap-1"
                              onClick={() => resendMutation.mutate({ invitationId: inv.id })}
                              disabled={resendMutation.isPending}
                            >
                              <RefreshCw className="w-3 h-3" /> Resend
                            </Button>
                            <Button
                              variant="ghost" size="sm" className="h-7 text-xs gap-1 text-red-500 hover:text-red-700"
                              onClick={() => revokeMutation.mutate({ invitationId: inv.id })}
                              disabled={revokeMutation.isPending}
                            >
                              <XCircle className="w-3 h-3" /> Revoke
                            </Button>
                          </>
                        )}
                        {(inv.status === "expired") && (
                          <Button
                            variant="ghost" size="sm" className="h-7 text-xs gap-1"
                            onClick={() => resendMutation.mutate({ invitationId: inv.id })}
                            disabled={resendMutation.isPending}
                          >
                            <RefreshCw className="w-3 h-3" /> Resend
                          </Button>
                        )}
                        {inv.status === "accepted" && (
                          <span className="text-xs" style={{ color: "#16a34a" }}>
                            {inv.acceptedAt ? `Accepted ${new Date(inv.acceptedAt).toLocaleDateString(undefined, { month: "short", day: "numeric" })}` : "Accepted"}
                          </span>
                        )}
                        {inv.status === "revoked" && (
                          <span className="text-xs italic" style={{ color: "#a8a29e" }}>Revoked</span>
                        )}
                      </div>
                    </td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </ScrollArea>
      </div>
    </div>
  );
}

/* ─── Activity Log Tab ─── */
function ActivityLogTab() {
  const { data: logs, isLoading } = trpc.auditLogs.list.useQuery({ limit: 100 });

  return (
    <div className="space-y-4">
      <div className="rounded-xl border overflow-hidden" style={{ background: "#fff", borderColor: "#e7e0d5" }}>
        <ScrollArea className="max-h-[600px]">
          {isLoading ? (
            <div className="text-center py-12">
              <div className="animate-spin w-6 h-6 border-2 rounded-full mx-auto" style={{ borderColor: "#14532D", borderTopColor: "transparent" }} />
              <p className="text-sm mt-2" style={{ color: "#a8a29e" }}>Loading activity...</p>
            </div>
          ) : !logs || logs.length === 0 ? (
            <div className="text-center py-12">
              <History className="w-8 h-8 mx-auto mb-2" style={{ color: "#d6d3d1" }} />
              <p className="text-sm" style={{ color: "#a8a29e" }}>No activity recorded yet</p>
            </div>
          ) : (
            <div className="divide-y" style={{ borderColor: "#e7e0d5" }}>
              {logs.map((log: any) => {
                const actionConfig = AUDIT_ACTION_LABELS[log.action] || { label: log.action, color: "#78716C" };
                const details = log.details as Record<string, any> | null;
                return (
                  <div key={log.id} className="px-4 py-3 hover:bg-black/[0.02] transition-colors">
                    <div className="flex items-start gap-3">
                      <div className="w-8 h-8 rounded-lg flex items-center justify-center shrink-0 mt-0.5" style={{ background: actionConfig.color + "14", color: actionConfig.color }}>
                        <History className="w-4 h-4" />
                      </div>
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center gap-2 flex-wrap">
                          <span className="text-xs font-semibold px-2 py-0.5 rounded-full" style={{ background: actionConfig.color + "14", color: actionConfig.color }}>
                            {actionConfig.label}
                          </span>
                          <span className="text-xs" style={{ color: "#a8a29e" }}>
                            {log.createdAt ? new Date(log.createdAt).toLocaleString(undefined, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : ""}
                          </span>
                        </div>
                        <p className="text-sm mt-1" style={{ color: "#292524", fontFamily: "'Source Sans 3', sans-serif" }}>
                          <strong>{log.actorName || "System"}</strong>
                          {log.action === "role_change" && details && (
                            <> changed <strong>{log.targetName}</strong>'s role from {details.previousRole} to {details.newRole}</>
                          )}
                          {log.action === "user_deleted" && (
                            <> deleted user <strong>{log.targetName}</strong></>
                          )}
                          {log.action === "invitation_sent" && details && (
                            <> invited <strong>{log.targetName}</strong> as {details.role}</>
                          )}
                          {log.action === "invitation_resent" && (
                            <> resent invitation to <strong>{log.targetName}</strong></>
                          )}
                          {log.action === "invitation_revoked" && (
                            <> revoked invitation for <strong>{log.targetName}</strong></>
                          )}
                          {log.action === "invitation_accepted" && (
                            <> accepted invitation for <strong>{log.targetName}</strong></>
                          )}
                          {log.action === "bulk_role_change" && details && (
                            <> changed {details.userIds?.length} users to {details.newRole}</>
                          )}
                          {log.action === "bulk_delete" && details && (
                            <> deleted {details.userIds?.length} users</>
                          )}
                        </p>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </ScrollArea>
      </div>
    </div>
  );
}

/* ─── Main Component ─── */
export default function UserManagement() {
  const [inviteDialogOpen, setInviteDialogOpen] = useState(false);
  const { data: usersList } = trpc.users.list.useQuery();
  const { data: invitationsList } = trpc.invitations.list.useQuery();

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-start justify-between">
        <div>
          <h1 className="text-2xl font-bold" style={{ fontFamily: "'Playfair Display', serif", color: "#292524" }}>
            User Management
          </h1>
          <p className="text-sm mt-1" style={{ color: "#78716C", fontFamily: "'Source Sans 3', sans-serif" }}>
            Manage users, send invitations, and track team activity.
          </p>
        </div>
        <Button onClick={() => setInviteDialogOpen(true)} className="text-white gap-2" style={{ background: "#14532D" }}>
          <UserPlus className="w-4 h-4" /> Invite Member
        </Button>
      </div>

      {/* Stats */}
      <RoleStats users={usersList || []} invitations={invitationsList || []} />

      {/* Role Legend */}
      <div className="p-4 rounded-xl border" style={{ background: "#fff", borderColor: "#e7e0d5" }}>
        <h3 className="text-sm font-semibold mb-3" style={{ color: "#292524", fontFamily: "'Source Sans 3', sans-serif" }}>
          Role Permissions
        </h3>
        <div className="grid sm:grid-cols-3 gap-3">
          {Object.entries(ROLE_CONFIG).map(([key, config]) => (
            <div key={key} className="flex items-start gap-3 p-3 rounded-lg" style={{ background: config.bg }}>
              <div className="w-8 h-8 rounded-lg flex items-center justify-center shrink-0 mt-0.5" style={{ background: config.color + "20", color: config.color }}>
                {config.icon}
              </div>
              <div>
                <div className="text-sm font-semibold" style={{ color: config.color }}>{config.label}</div>
                <div className="text-xs mt-0.5" style={{ color: "#78716C" }}>{config.description}</div>
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* Tabs */}
      <Tabs defaultValue="users" className="w-full">
        <TabsList className="w-full justify-start border-b rounded-none bg-transparent p-0 h-auto" style={{ borderColor: "#e7e0d5" }}>
          <TabsTrigger
            value="users"
            className="rounded-none border-b-2 border-transparent data-[state=active]:border-[#14532D] data-[state=active]:text-[#14532D] data-[state=active]:shadow-none px-4 py-2.5 text-sm"
            style={{ fontFamily: "'Source Sans 3', sans-serif" }}
          >
            <Users className="w-4 h-4 mr-2" /> Users
          </TabsTrigger>
          <TabsTrigger
            value="invitations"
            className="rounded-none border-b-2 border-transparent data-[state=active]:border-[#14532D] data-[state=active]:text-[#14532D] data-[state=active]:shadow-none px-4 py-2.5 text-sm"
            style={{ fontFamily: "'Source Sans 3', sans-serif" }}
          >
            <Mail className="w-4 h-4 mr-2" /> Invitations
          </TabsTrigger>
          <TabsTrigger
            value="activity"
            className="rounded-none border-b-2 border-transparent data-[state=active]:border-[#14532D] data-[state=active]:text-[#14532D] data-[state=active]:shadow-none px-4 py-2.5 text-sm"
            style={{ fontFamily: "'Source Sans 3', sans-serif" }}
          >
            <History className="w-4 h-4 mr-2" /> Activity Log
          </TabsTrigger>
        </TabsList>

        <TabsContent value="users" className="mt-4">
          <UsersTab />
        </TabsContent>
        <TabsContent value="invitations" className="mt-4">
          <InvitationsTab />
        </TabsContent>
        <TabsContent value="activity" className="mt-4">
          <ActivityLogTab />
        </TabsContent>
      </Tabs>

      {/* Send Invitation Dialog */}
      <SendInviteDialog open={inviteDialogOpen} onOpenChange={setInviteDialogOpen} />
    </div>
  );
}
