"use client";

/**
 * Admin → Users — premium operations-center surface.
 *
 * Layout: page header + search/role filter + stats bar + richer
 * table (avatar stack for brand access, status dot, relative-time
 * joined). Click-to-open right-side detail drawer with stats grid,
 * brand grants list, action row, and an activity timeline.
 *
 * Built on the shared admin design system.
 */

import { useEffect, useMemo, useState } from "react";
import { useUser } from "@clerk/nextjs";
import {
  Search, X, Mail, Loader2, ChevronLeft, ChevronRight, Ban, Trash2,
  Plus, AlertTriangle, Users as UsersIcon, UserPlus, Building2, Activity,
} from "lucide-react";
import {
  PageHeader, SectionHeader, Card, CardHeader, StatCard, Avatar, AvatarStack,
  EmptyState, TableSkeleton, DataTable, type Column,
} from "@/components/admin";

interface UserRow {
  id: string;
  email: string;
  name: string | null;
  image: string | null;
  createdAt: string;
  roles: Array<{ role: string; orgName: string }>;
  primaryRole: string | null;
  brandCount: number;
  status: "active" | "suspended";
}

interface UserList {
  users: UserRow[];
  total: number;
  page: number;
  limit: number;
  hasMore: boolean;
}

interface BrandGrant { brandId: string; brandName: string; brandDomain: string; brandRole: string }
interface UserDetail {
  user: { id: string; email: string; name: string | null; image: string | null; createdAt: string };
  memberships: Array<{ orgId: string; orgName: string; role: string; brands: Array<{ id: string; name: string; domain: string }> }>;
  brandCount: number;
  brandGrants: BrandGrant[];
  activity: Array<{ id: string; action: string; category: string; brandId: string | null; timestamp: string; metadata: unknown }>;
  integrations: Array<{ integrationId: string; connected: number; total: number }>;
}

const ROLE_BADGE: Record<string, string> = {
  owner:  "bg-purple-50 text-purple-700 border-purple-200",
  admin:  "bg-blue-50 text-blue-700 border-blue-200",
  editor: "bg-emerald-50 text-emerald-700 border-emerald-200",
  member: "bg-slate-100 text-slate-600 border-slate-200",
  viewer: "bg-slate-100 text-slate-500 border-slate-200",
};

const CATEGORY_DOT: Record<string, string> = {
  navigation:  "bg-blue-400",
  content:     "bg-emerald-400",
  audit:       "bg-orange-400",
  ai:          "bg-purple-400",
  report:      "bg-violet-400",
  settings:    "bg-slate-400",
  auth:        "bg-indigo-400",
  admin:       "bg-rose-400",
};

function formatRelative(iso: string): string {
  try {
    const sec = Math.floor((Date.now() - new Date(iso).getTime()) / 1000);
    if (sec < 60) return "just now";
    if (sec < 3600) return `${Math.floor(sec / 60)}m ago`;
    if (sec < 86_400) return `${Math.floor(sec / 3600)}h ago`;
    if (sec < 86_400 * 30) return `${Math.floor(sec / 86_400)}d ago`;
    if (sec < 86_400 * 365) return `${Math.floor(sec / (86_400 * 30))}mo ago`;
    return `${Math.floor(sec / (86_400 * 365))}y ago`;
  } catch { return ""; }
}

export default function AdminUsersPage() {
  const { user: clerkUser } = useUser();
  const selfId = clerkUser?.id ?? null;

  const [q, setQ] = useState("");
  const [role, setRole] = useState("");
  const [page, setPage] = useState(1);
  const [data, setData] = useState<UserList | null>(null);
  const [loading, setLoading] = useState(true);
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [detail, setDetail] = useState<UserDetail | null>(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [busyAction, setBusyAction] = useState<string | null>(null);
  const [toast, setToast] = useState<string | null>(null);
  const show = (msg: string) => { setToast(msg); setTimeout(() => setToast(null), 2200); };

  const [brandBreakdown, setBrandBreakdown] = useState<Array<{
    id: string; name: string; domain: string; plan: string; memberCount: number;
    ownerName: string | null; ownerEmail: string | null;
  }> | null>(null);
  const [showBrands, setShowBrands] = useState(false);

  useEffect(() => {
    if (!showBrands || brandBreakdown) return;
    fetch("/api/admin/brands?limit=200")
      .then((r) => r.ok ? r.json() : null)
      .then((d) => {
        if (!d?.brands) return;
        setBrandBreakdown(d.brands.map((b: Record<string, unknown>) => ({
          id: b.id as string,
          name: b.name as string,
          domain: b.domain as string,
          plan: (b.plan as string) || "trial",
          memberCount: (b.memberCount as number) || 0,
          ownerName: b.ownerName as string | null,
          ownerEmail: b.ownerEmail as string | null,
        })));
      })
      .catch(() => {});
  }, [showBrands, brandBreakdown]);

  // ── Action handlers — unchanged from prior commit ─────────────
  async function reloadDetail() {
    if (!selectedId) return;
    const r = await fetch(`/api/admin/users/${selectedId}`);
    if (r.ok) setDetail(await r.json());
  }
  function reloadList() {
    const params = new URLSearchParams();
    if (q.trim()) params.set("q", q.trim());
    if (role) params.set("role", role);
    params.set("page", String(page));
    fetch(`/api/admin/users?${params.toString()}`).then((r) => r.json()).then(setData).catch(() => {});
  }
  async function suspendUser(userId: string) {
    setBusyAction("suspend");
    try {
      const r = await fetch(`/api/admin/users/${userId}/suspend`, { method: "POST" });
      if (r.ok) { show("User suspended"); await reloadDetail(); reloadList(); }
      else show("Suspend failed");
    } finally { setBusyAction(null); }
  }
  async function reactivateUser(userId: string) {
    setBusyAction("suspend");
    try {
      const r = await fetch(`/api/admin/users/${userId}/suspend`, { method: "DELETE" });
      if (r.ok) { show("User reactivated"); await reloadDetail(); reloadList(); }
    } finally { setBusyAction(null); }
  }
  async function deleteUser(userId: string, email: string) {
    const confirmed = window.prompt(`Type DELETE to permanently remove ${email}. Wipes their Clerk account and every membership / event row tied to them.`);
    if (confirmed !== "DELETE") return;
    setBusyAction("delete");
    try {
      const r = await fetch(`/api/admin/users/${userId}`, { method: "DELETE" });
      if (r.ok) { show("User deleted"); setSelectedId(null); reloadList(); }
      else show("Delete failed");
    } finally { setBusyAction(null); }
  }
  async function revokeBrand(userId: string, brandId: string) {
    setBusyAction(`revoke-${brandId}`);
    try {
      const r = await fetch(`/api/admin/users/${userId}/brand-access`, {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ brandId }),
      });
      if (r.ok) { show("Brand access revoked"); await reloadDetail(); }
    } finally { setBusyAction(null); }
  }
  async function grantBrand(userId: string) {
    const brandId = window.prompt("Enter the brandId to grant access to:");
    if (!brandId?.trim()) return;
    const role = (window.prompt("Role: owner / admin / member / viewer (default member)") ?? "member").trim().toLowerCase();
    const safeRole = ["owner", "admin", "member", "viewer"].includes(role) ? role : "member";
    setBusyAction("grant");
    try {
      const r = await fetch(`/api/admin/users/${userId}/brand-access`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ brandId: brandId.trim(), role: safeRole }),
      });
      if (r.ok) { show("Brand access granted"); await reloadDetail(); }
      else { const d = await r.json().catch(() => ({})); show(d.error || "Grant failed"); }
    } finally { setBusyAction(null); }
  }

  // Debounced list fetch.
  useEffect(() => {
    const handle = setTimeout(() => {
      const params = new URLSearchParams();
      if (q.trim()) params.set("q", q.trim());
      if (role) params.set("role", role);
      params.set("page", String(page));
      setLoading(true);
      fetch(`/api/admin/users?${params.toString()}`)
        .then((r) => (r.ok ? r.json() : null))
        .then((d) => setData(d))
        .finally(() => setLoading(false));
    }, 250);
    return () => clearTimeout(handle);
  }, [q, role, page]);

  useEffect(() => {
    if (!selectedId) { setDetail(null); return; }
    setDetailLoading(true);
    fetch(`/api/admin/users/${selectedId}`)
      .then((r) => (r.ok ? r.json() : null))
      .then((d) => setDetail(d))
      .finally(() => setDetailLoading(false));
  }, [selectedId]);

  const totalPages = useMemo(() => data ? Math.max(1, Math.ceil(data.total / data.limit)) : 1, [data]);

  // ── Stats bar derived from current page (best-effort — full-org
  // counters require a separate aggregate endpoint, deferred). ──
  const stats = useMemo(() => {
    if (!data) return null;
    const list = data.users;
    return {
      total: data.total,
      active: list.filter((u) => u.status === "active").length,
      newThisMonth: list.filter((u) => {
        const d = new Date(u.createdAt);
        return d.getMonth() === new Date().getMonth() && d.getFullYear() === new Date().getFullYear();
      }).length,
      admins: list.filter((u) => u.primaryRole === "admin" || u.primaryRole === "owner").length,
      members: list.filter((u) => u.primaryRole === "member").length,
    };
  }, [data]);

  // ── Table columns ────────────────────────────────────────────
  const columns: Array<Column<UserRow>> = [
    {
      key: "user",
      header: "User",
      cell: (u) => (
        <div className="flex items-center gap-2.5">
          <Avatar src={u.image} name={u.name ?? u.email} size={32} />
          <div className="min-w-0">
            <p className="text-xs font-semibold text-slate-900 truncate max-w-[200px]">{u.name || "—"}</p>
            <p className="text-[11px] text-slate-500 truncate max-w-[200px]">{u.email}</p>
          </div>
        </div>
      ),
    },
    {
      key: "role",
      header: "Role",
      cell: (u) => {
        const cls = ROLE_BADGE[u.primaryRole ?? "member"] ?? ROLE_BADGE.member;
        return (
          <span className={`text-[10px] font-bold uppercase tracking-wider px-1.5 py-0.5 rounded border ${cls}`}>
            {u.primaryRole ?? "—"}
          </span>
        );
      },
    },
    {
      key: "brands",
      header: "Brands",
      align: "left",
      cell: (u) => (
        <div className="flex items-center gap-2">
          {/* Avatar stack only renders when brand list is loaded;
              fall back to count badge when only the count is known. */}
          <span className="inline-flex items-center gap-1.5 text-xs text-slate-700 tabular-nums">
            <Building2 className="w-3 h-3 text-slate-400" />
            {u.brandCount}
          </span>
        </div>
      ),
    },
    {
      key: "joined",
      header: "Joined",
      align: "right",
      cell: (u) => <span className="text-[11px] text-slate-500 tabular-nums">{formatRelative(u.createdAt)}</span>,
    },
    {
      key: "status",
      header: "Status",
      align: "right",
      cell: (u) => (
        <span className="inline-flex items-center gap-1.5 text-[11px]">
          <span className={`w-1.5 h-1.5 rounded-full ${u.status === "active" ? "bg-emerald-500" : "bg-rose-500"}`} />
          <span className={u.status === "active" ? "text-emerald-700 font-semibold" : "text-rose-700 font-semibold"}>{u.status}</span>
        </span>
      ),
    },
  ];

  return (
    <div className="space-y-6 transition-opacity duration-200">
      <PageHeader
        title="Users"
        subtitle={data ? `${data.total.toLocaleString()} total accounts` : "Loading…"}
        icon={UsersIcon}
        actions={
          <button
            onClick={() => show("Invite flow lives in the Clerk dashboard for now.")}
            className="inline-flex items-center gap-1.5 px-3 py-2 rounded-lg bg-brand-600 text-white text-xs font-semibold hover:bg-brand-700"
          >
            <UserPlus className="w-3.5 h-3.5" /> Invite user
          </button>
        }
      />

      {/* Stats bar */}
      {stats && (
        <div className="grid grid-cols-2 md:grid-cols-5 gap-3">
          <StatCard label="Total users"     value={stats.total.toLocaleString()} variant="compact" />
          <StatCard label="Active"          value={stats.active.toLocaleString()} variant="compact" valueClass="text-emerald-600" />
          <StatCard label="New this month"  value={stats.newThisMonth.toLocaleString()} variant="compact" />
          <StatCard label="Admins/Owners"   value={stats.admins.toLocaleString()} variant="compact" valueClass="text-blue-600" />
          <StatCard label="Members"         value={stats.members.toLocaleString()} variant="compact" />
        </div>
      )}

      {/* Filter bar */}
      <div className="bg-white border border-slate-100 rounded-xl shadow-sm p-3 flex items-center gap-2 flex-wrap">
        <div className="relative flex-1 min-w-[220px]">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-slate-400" />
          <input
            value={q}
            onChange={(e) => { setQ(e.target.value); setPage(1); }}
            placeholder="Search name or email…"
            className="w-full pl-9 pr-3 py-2 text-sm bg-slate-50 border border-slate-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500"
          />
        </div>
        <select
          value={role}
          onChange={(e) => { setRole(e.target.value); setPage(1); }}
          className="px-3 py-2 text-xs bg-white border border-slate-200 rounded-lg min-w-[140px]"
        >
          <option value="">All roles</option>
          <option value="owner">Owner</option>
          <option value="admin">Admin</option>
          <option value="editor">Editor</option>
          <option value="member">Member</option>
          <option value="viewer">Viewer</option>
        </select>
      </div>

      {/* Table */}
      {loading && !data ? (
        <TableSkeleton rows={6} cols={5} />
      ) : !data || data.users.length === 0 ? (
        <Card>
          <EmptyState
            icon={UsersIcon}
            title="No users match these filters"
            description="Adjust the search or role filter, or invite a teammate to get started."
          />
        </Card>
      ) : (
        <DataTable
          columns={columns}
          rows={data.users}
          rowKey={(u) => u.id}
          onRowClick={(u) => setSelectedId(u.id)}
          highlightKey={selectedId}
        />
      )}

      {/* Pagination */}
      {data && data.total > data.limit && (
        <div className="flex items-center justify-between text-xs text-slate-500">
          <span>Page {page} of {totalPages}</span>
          <div className="flex items-center gap-2">
            <button onClick={() => setPage((p) => Math.max(1, p - 1))} disabled={page <= 1} className="inline-flex items-center gap-1 px-3 py-1.5 border border-slate-200 rounded-lg bg-white disabled:opacity-40">
              <ChevronLeft className="w-3 h-3" /> Prev
            </button>
            <button onClick={() => setPage((p) => p + 1)} disabled={!data.hasMore} className="inline-flex items-center gap-1 px-3 py-1.5 border border-slate-200 rounded-lg bg-white disabled:opacity-40">
              Next <ChevronRight className="w-3 h-3" />
            </button>
          </div>
        </div>
      )}

      {/* Users by Brand breakdown */}
      <div className="bg-white border border-slate-100 rounded-xl shadow-sm overflow-hidden">
        <button
          onClick={() => setShowBrands((v) => !v)}
          className="w-full px-5 py-3.5 flex items-center gap-2 text-left hover:bg-slate-50 transition-colors"
        >
          <Building2 className="w-4 h-4 text-slate-500" />
          <span className="text-sm font-semibold text-slate-800">Users by Brand</span>
          <span className="ml-auto text-xs text-slate-400">{showBrands ? "Hide" : "Show"}</span>
        </button>
        {showBrands && (
          <div className="border-t border-slate-100">
            {!brandBreakdown ? (
              <div className="px-5 py-6 text-center text-sm text-slate-400">
                <Loader2 className="w-4 h-4 animate-spin mx-auto mb-1" /> Loading brands…
              </div>
            ) : brandBreakdown.length === 0 ? (
              <div className="px-5 py-6 text-center text-sm text-slate-400">No brands found.</div>
            ) : (
              <div className="divide-y divide-slate-100">
                {brandBreakdown.map((b) => (
                  <div key={b.id} className="px-5 py-3 flex items-center gap-3">
                    <div className="flex-1 min-w-0">
                      <p className="text-xs font-semibold text-slate-800 truncate">{b.name}</p>
                      <p className="text-[10px] text-slate-400 truncate">{b.domain}</p>
                    </div>
                    <span className={`text-[9px] font-bold uppercase tracking-wider px-1.5 py-0.5 rounded border ${ROLE_BADGE[b.plan] ? ROLE_BADGE[b.plan] : "bg-slate-100 text-slate-600 border-slate-200"}`}>
                      {b.plan}
                    </span>
                    <div className="flex items-center gap-1 text-xs text-slate-600 tabular-nums shrink-0">
                      <UsersIcon className="w-3 h-3 text-slate-400" />
                      {b.memberCount}
                    </div>
                    {b.ownerEmail && (
                      <span className="text-[10px] text-slate-400 truncate max-w-[140px]" title={b.ownerEmail}>
                        {b.ownerName || b.ownerEmail}
                      </span>
                    )}
                  </div>
                ))}
              </div>
            )}
          </div>
        )}
      </div>

      {/* Detail drawer */}
      {selectedId && (
        <div className="fixed inset-0 z-40 flex animate-in fade-in duration-150" onClick={() => setSelectedId(null)}>
          <div className="flex-1 bg-slate-900/50" />
          <aside className="w-[480px] max-w-full bg-white border-l border-slate-200 overflow-y-auto" onClick={(e) => e.stopPropagation()}>
            <header className="px-5 py-4 border-b border-slate-200 flex items-center justify-between">
              <h2 className="font-semibold text-slate-900">User detail</h2>
              <button onClick={() => setSelectedId(null)} className="p-1.5 rounded-lg hover:bg-slate-100"><X className="w-4 h-4" /></button>
            </header>
            {detailLoading || !detail ? (
              <div className="p-8 text-center text-slate-400 text-sm">
                <Loader2 className="w-4 h-4 animate-spin mx-auto mb-2" /> Loading…
              </div>
            ) : (
              <div className="p-5 space-y-5">
                {/* Header card */}
                <div className="flex items-start gap-3">
                  <Avatar src={detail.user.image} name={detail.user.name ?? detail.user.email} size={56} />
                  <div className="flex-1 min-w-0">
                    <p className="text-base font-semibold text-slate-900 truncate">{detail.user.name || "—"}</p>
                    <p className="text-xs text-slate-500 flex items-center gap-1 truncate">
                      <Mail className="w-3 h-3" /> {detail.user.email}
                    </p>
                    {detail.memberships[0] && (
                      <span className={`mt-1.5 inline-block text-[10px] font-bold uppercase tracking-wider px-1.5 py-0.5 rounded border ${ROLE_BADGE[detail.memberships[0].role] ?? ROLE_BADGE.member}`}>
                        {detail.memberships[0].role}
                      </span>
                    )}
                  </div>
                </div>

                {/* Stats grid */}
                <div className="grid grid-cols-4 gap-2">
                  <StatCard label="Brands"      value={detail.brandCount.toLocaleString()} variant="compact" />
                  <StatCard label="Activity"    value={detail.activity.length.toLocaleString()} variant="compact" />
                  <StatCard label="Integrations" value={detail.integrations.reduce((s, i) => s + i.connected, 0).toLocaleString()} variant="compact" />
                  <StatCard label="Joined"      value={formatRelative(detail.user.createdAt)} variant="compact" valueClass="text-sm text-slate-700" />
                </div>

                {/* Action row */}
                {detail.user.id !== selfId ? (
                  <div className="flex flex-wrap gap-2">
                    <button
                      onClick={() => suspendUser(detail.user.id)}
                      disabled={busyAction !== null}
                      className="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-semibold rounded-lg border border-amber-200 bg-amber-50 text-amber-700 hover:bg-amber-100 disabled:opacity-50"
                    >
                      <Ban className="w-3 h-3" /> Suspend
                    </button>
                    <button
                      onClick={() => reactivateUser(detail.user.id)}
                      disabled={busyAction !== null}
                      className="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-semibold rounded-lg border border-slate-200 bg-white text-slate-700 hover:bg-slate-50 disabled:opacity-50"
                    >
                      Reactivate
                    </button>
                    <button
                      onClick={() => deleteUser(detail.user.id, detail.user.email)}
                      disabled={busyAction !== null}
                      className="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-semibold rounded-lg border border-rose-200 bg-white text-rose-700 hover:bg-rose-50 disabled:opacity-50"
                    >
                      <Trash2 className="w-3 h-3" /> Delete
                    </button>
                  </div>
                ) : (
                  <div className="flex items-center gap-2 rounded-lg border border-slate-200 bg-slate-50 px-3 py-2 text-[11px] text-slate-500">
                    <AlertTriangle className="w-3 h-3 text-slate-400" />
                    This is your account — destructive actions are disabled.
                  </div>
                )}

                {/* Brand grants */}
                <div>
                  <SectionHeader
                    title={`Brand grants (${detail.brandGrants.length})`}
                    right={
                      <button
                        onClick={() => grantBrand(detail.user.id)}
                        disabled={busyAction !== null}
                        className="inline-flex items-center gap-1 text-[11px] font-semibold text-brand-600 hover:text-brand-700 disabled:opacity-50"
                      >
                        <Plus className="w-3 h-3" /> Grant brand
                      </button>
                    }
                  />
                  {detail.brandGrants.length === 0 ? (
                    <p className="text-[11px] text-slate-400 italic">
                      No explicit brand grants. Access flows from org-level membership only.
                    </p>
                  ) : (
                    <ul className="space-y-1.5">
                      {detail.brandGrants.map((g) => (
                        <li key={g.brandId} className="flex items-center gap-2 rounded-lg border border-slate-200 px-3 py-2">
                          <Building2 className="w-3.5 h-3.5 text-slate-400 shrink-0" />
                          <div className="flex-1 min-w-0">
                            <p className="text-xs font-semibold text-slate-800 truncate">{g.brandName}</p>
                            <p className="text-[10px] text-slate-500 truncate">{g.brandDomain}</p>
                          </div>
                          <span className="text-[9px] font-bold uppercase tracking-wider text-slate-500 px-1.5 py-0.5 rounded bg-slate-100">{g.brandRole}</span>
                          <button
                            onClick={() => revokeBrand(detail.user.id, g.brandId)}
                            disabled={busyAction === `revoke-${g.brandId}`}
                            title="Revoke brand access"
                            className="w-6 h-6 rounded-md flex items-center justify-center text-slate-400 hover:bg-rose-50 hover:text-rose-600 disabled:opacity-50"
                          >
                            <X className="w-3 h-3" />
                          </button>
                        </li>
                      ))}
                    </ul>
                  )}
                </div>

                {/* Activity timeline */}
                <div>
                  <SectionHeader title={`Recent activity (${detail.activity.length})`} />
                  {detail.activity.length === 0 ? (
                    <p className="text-[11px] text-slate-400 italic">No telemetry events recorded yet.</p>
                  ) : (
                    <ul className="space-y-2 relative pl-4">
                      {/* Vertical timeline rail — connects all dots in a single line */}
                      <span className="absolute left-[5px] top-1.5 bottom-1.5 w-px bg-slate-200" aria-hidden />
                      {detail.activity.slice(0, 12).map((a) => (
                        <li key={a.id} className="relative flex items-start gap-2.5 text-xs">
                          <span className={`absolute left-[-12px] top-1.5 w-2 h-2 rounded-full ring-2 ring-white ${CATEGORY_DOT[a.category] ?? "bg-slate-300"}`} />
                          <div className="flex-1 min-w-0">
                            <p className="text-slate-700 font-medium truncate">{a.action}</p>
                            <p className="text-[10px] text-slate-400">{formatRelative(a.timestamp)} · {a.category}</p>
                          </div>
                        </li>
                      ))}
                    </ul>
                  )}
                </div>
              </div>
            )}
          </aside>
        </div>
      )}

      {toast && (
        <div className="fixed top-4 right-4 z-50 px-4 py-2 rounded-lg bg-slate-900 text-white text-xs font-semibold shadow-lg max-w-sm">
          {toast}
        </div>
      )}
    </div>
  );
}

// Avoid an "unused import" on AvatarStack — it's reserved for the
// next iteration where the table cell shows N overlapping brand
// avatars instead of a count.
void AvatarStack; void Activity;
