import { useState, useEffect, useCallback } from "react";
import {
  Download, Globe, Lock, Search, Filter, RefreshCw, ChevronLeft, ChevronRight,
  LogIn, Key, UserPlus, Shield, Settings,
  AlertTriangle, Terminal, Loader2, X,
  CheckCircle2, XCircle, Link2, UserCog,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import { api, AuditLogEntry, ApiError, OrganizationMember } from "@/lib/api";
import { useCurrentOrganizationId } from "@/hooks/useCurrentOrganization";
import { formatDateTime } from "@/lib/date";

// ─── category / display helpers ──────────────────────────────────────────────

type Category = "auth" | "ssh" | "admin" | "member" | "policy" | "security" | "oauth" | "other";

const getCategory = (action: string): Category => {
  const a = action.toLowerCase();
  if (a.startsWith("session") || a === "user.login" || a === "user.logout") return "auth";
  if (a.startsWith("ssh"))                                                   return "ssh";
  if (a.startsWith("admin."))                                                return "admin";
  if (a.includes("member") || a.includes("invite") || a.startsWith("org.member")) return "member";
  if (a.includes("policy") || a.includes("mfa.policy") || a.startsWith("org.security")) return "policy";
  if (a.includes("mfa") || a.includes("totp") || a.includes("webauthn") || a.includes("passkey") || a.includes("password")) return "security";
  if (a.startsWith("external_auth"))                                         return "oauth";
  return "other";
};

const CATEGORY_META: Record<Category, { label: string; color: string }> = {
  auth:     { label: "Auth",     color: "bg-blue-500/10 text-blue-600 dark:text-blue-400" },
  ssh:      { label: "SSH",      color: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400" },
  admin:    { label: "Admin",    color: "bg-red-500/10 text-red-600 dark:text-red-400" },
  member:   { label: "Member",   color: "bg-violet-500/10 text-violet-600 dark:text-violet-400" },
  policy:   { label: "Policy",   color: "bg-amber-500/10 text-amber-600 dark:text-amber-400" },
  security: { label: "Security", color: "bg-orange-500/10 text-orange-600 dark:text-orange-400" },
  oauth:    { label: "OAuth",    color: "bg-cyan-500/10 text-cyan-600 dark:text-cyan-400" },
  other:    { label: "Other",    color: "bg-muted text-muted-foreground" },
};

const getCategoryIcon = (cat: Category) => {
  const cls = "w-4 h-4";
  switch (cat) {
    case "auth":     return <LogIn className={cls} />;
    case "ssh":      return <Terminal className={cls} />;
    case "admin":    return <UserCog className={cls} />;
    case "member":   return <UserPlus className={cls} />;
    case "policy":   return <Settings className={cls} />;
    case "security": return <Shield className={cls} />;
    case "oauth":    return <Link2 className={cls} />;
    default:         return <Key className={cls} />;
  }
};

const ACTION_LABELS: Record<string, string> = {
  // Sessions
  "session.create":  "Signed in",
  "session.revoke":  "Signed out",
  "user.login":      "Signed in",
  "user.logout":     "Signed out",
  // Members
  "org.member.add":         "Member added",
  "org.member.remove":      "Member removed",
  "org.member.role_change": "Member role changed",
  "org.ownership.transferred": "Ownership transferred",
  // Admin actions
  "admin.mfa.remove":    "MFA removed by admin",
  "admin.oauth.unlink":  "OAuth unlinked by admin",
  "admin.password.set":  "Password set by admin",
  "admin.email.verify":  "Email verified by admin",
  // Security / policy
  "org.security_policy.update":          "Security policy updated",
  "user.security_policy.override_update":"User policy override updated",
  "mfa.policy.user_suspended":            "User suspended (MFA policy)",
  "mfa.policy.user_compliant":            "User MFA compliant",
  // Password
  "user.password_change": "Password changed",
  "user.password_reset":  "Password reset",
  // SSH
  "ssh.key.added":             "SSH key added",
  "ssh.key.verified":          "SSH key verified",
  "ssh.key.deleted":           "SSH key removed",
  "ssh.cert.requested":        "SSH certificate requested",
  "ssh.cert.issued":           "SSH certificate issued",
  "ssh.cert.failed":           "SSH certificate request failed",
  "ssh.cert.revoked":          "SSH certificate revoked",
  // WebAuthn / Passkey
  "webauthn.register.completed": "Passkey registered",
  "webauthn.credential.deleted": "Passkey removed",
  "webauthn.login.success":      "Signed in with passkey",
  "webauthn.login.failed":       "Passkey login failed",
  // TOTP
  "totp.enroll.completed":  "TOTP enrolled",
  "totp.disabled":          "TOTP disabled",
  "totp.verify.failed":     "TOTP verification failed",
  // External auth
  "external_auth.link.completed": "OAuth account linked",
  "external_auth.unlink":         "OAuth account unlinked",
  "external_auth.login":          "Signed in via OAuth",
  "external_auth.login.failed":   "OAuth login failed",
  // Org
  "org.create": "Organisation created",
  "org.update": "Organisation updated",
  "org.delete": "Organisation deleted",
  // User lifecycle
  "user.register": "User registered",
  "user.suspend":  "User suspended",
  "user.unsuspend":"User unsuspended",
  "user.delete":   "User deleted",
};

const getActionLabel = (action: string) =>
  ACTION_LABELS[action] ??
  action.replace(/[._]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());

// ─── action filter options (value = enum dot-notation) ───────────────────────

const ACTION_FILTER_OPTIONS = [
  { value: "all",                           label: "All actions" },
  // Auth
  { value: "session.create",                label: "Sign in" },
  { value: "session.revoke",                label: "Sign out" },
  { value: "external_auth.login",           label: "OAuth login" },
  // Members
  { value: "org.member.add",                label: "Member added" },
  { value: "org.member.remove",             label: "Member removed" },
  { value: "org.member.role_change",        label: "Role changed" },
  // Admin actions
  { value: "admin.mfa.remove",              label: "MFA removed (admin)" },
  { value: "admin.oauth.unlink",            label: "OAuth unlinked (admin)" },
  { value: "admin.password.set",            label: "Password set (admin)" },
  // Security / policy
  { value: "org.security_policy.update",    label: "Security policy changed" },
  { value: "user.password_change",          label: "Password changed" },
  { value: "user.password_reset",           label: "Password reset" },
  // SSH
  { value: "ssh.key.added",                 label: "SSH key added" },
  { value: "ssh.key.verified",              label: "SSH key verified" },
  { value: "ssh.cert.issued",               label: "SSH cert issued" },
  { value: "ssh.cert.revoked",              label: "SSH cert revoked" },
  // MFA
  { value: "totp.enroll.completed",         label: "TOTP enrolled" },
  { value: "totp.disabled",                 label: "TOTP disabled" },
  { value: "webauthn.register.completed",   label: "Passkey registered" },
  { value: "webauthn.credential.deleted",   label: "Passkey removed" },
  // User lifecycle
  { value: "user.register",                 label: "User registered" },
  { value: "user.suspend",                  label: "User suspended" },
];

const PER_PAGE = 50;

const getUserLabel = (log: AuditLogEntry) =>
  log.user?.email || (log.user_id ? `${log.user_id.slice(0, 8)}…` : null);

// ─── filter chip helpers ──────────────────────────────────────────────────────

const ACTION_CHIP_LABELS: Record<string, string> = {
  ...ACTION_LABELS,
  all: "All actions",
};

// ─── cert metadata detail ─────────────────────────────────────────────────────

function CertDetail({ metadata }: { metadata?: Record<string, unknown> | null }) {
  if (!metadata) return null;
  const principal = metadata.principal as string | undefined;
  const principals = metadata.principals as string[] | undefined;
  const serial = metadata.serial_number ?? metadata.serial ?? metadata.cert_serial;
  const principalList = principal ? [principal] : Array.isArray(principals) ? principals : [];
  if (!principalList.length && !serial) return null;
  return (
    <span className="text-xs text-muted-foreground ml-2">
      {principalList.length > 0 && <>principal: <span className="font-mono">{principalList.join(", ")}</span></>}
      {principalList.length > 0 && serial && " · "}
      {serial != null && <>serial: <span className="font-mono">{String(serial)}</span></>}
    </span>
  );
}

// ─── component ────────────────────────────────────────────────────────────────

export default function OrgAuditPage() {
  const { orgId } = useCurrentOrganizationId();

  const [search, setSearch]                   = useState("");
  const [debouncedSearch, setDebouncedSearch] = useState("");
  const [actionFilter, setActionFilter]       = useState("all");
  const [successFilter, setSuccessFilter]     = useState("all");
  const [userFilter, setUserFilter]           = useState<string | null>(null);
  const [userFilterLabel, setUserFilterLabel] = useState<string | null>(null);
  const [viewMode, setViewMode]               = useState<"org" | "user">("org");
  const [selectedUserId, setSelectedUserId]   = useState<string | null>(null);
  const [selectedUserLabel, setSelectedUserLabel] = useState<string | null>(null);
  const [orgMembers, setOrgMembers]           = useState<OrganizationMember[]>([]);
  const [isMembersLoading, setIsMembersLoading] = useState(false);
  const [accessDenied, setAccessDenied]       = useState(false);
  const [page, setPage]                       = useState(1);
  const [totalPages, setTotalPages]           = useState(1);
  const [totalCount, setTotalCount]           = useState(0);
  const [auditLogs, setAuditLogs]             = useState<AuditLogEntry[]>([]);
  const [isLoading, setIsLoading]             = useState(true);
  const [isExporting, setIsExporting]         = useState(false);
  const [error, setError]                     = useState<string | null>(null);

  // debounce search
  useEffect(() => {
    const t = setTimeout(() => setDebouncedSearch(search), 400);
    return () => clearTimeout(t);
  }, [search]);

  // reset page on filter change
  useEffect(() => { setPage(1); }, [actionFilter, successFilter, userFilter, debouncedSearch, viewMode, selectedUserId]);

  // fetch org members for user selector
  useEffect(() => {
    if (viewMode !== "user" || !orgId) return;
    setIsMembersLoading(true);
    api.organizations.getMembers(orgId)
      .then((resp) => setOrgMembers(resp.members ?? []))
      .catch(() => {})
      .finally(() => setIsMembersLoading(false));
  }, [viewMode, orgId]);

  const fetchLogs = useCallback(async () => {
    setIsLoading(true);
    setError(null);
    setAccessDenied(false);
    try {
      const params: Record<string, string> = {
        page: String(page),
        per_page: String(PER_PAGE),
      };
      if (actionFilter !== "all")  params.action  = actionFilter;
      if (successFilter !== "all") params.success = successFilter;
      if (userFilter)              params.user_id = userFilter;
      if (debouncedSearch)         params.q        = debouncedSearch;

      if (viewMode === "user") {
        if (!selectedUserId) { setIsLoading(false); return; }
        const resp = await api.superadmin.getUserAuditLogs(selectedUserId, params);
        setAuditLogs(resp.audit_logs ?? []);
        setTotalCount(resp.count ?? 0);
        setTotalPages(resp.pages ?? 1);
      } else {
        if (!orgId) { setIsLoading(false); return; }
        const resp = await api.organizations.getAuditLogs(orgId, params);
        setAuditLogs(resp.audit_logs ?? []);
        setTotalCount(resp.count ?? 0);
        setTotalPages(resp.pages ?? 1);
      }
    } catch (err) {
      if (err instanceof ApiError && err.code === 403) {
        setAccessDenied(true);
      } else {
        console.error("Failed to fetch audit logs:", err);
        setError("Failed to load audit logs. Please try again.");
      }
    } finally {
      setIsLoading(false);
    }
  }, [orgId, page, actionFilter, successFilter, userFilter, debouncedSearch, viewMode, selectedUserId]);

  useEffect(() => { fetchLogs(); }, [fetchLogs]);

  const handleExport = useCallback(async () => {
    setIsExporting(true);
    try {
      const EXPORT_PER_PAGE = 200;
      const buildParams = (p: number) => {
        const params: Record<string, string> = { page: String(p), per_page: String(EXPORT_PER_PAGE) };
        if (actionFilter !== "all")  params.action  = actionFilter;
        if (successFilter !== "all") params.success = successFilter;
        if (userFilter)              params.user_id = userFilter;
        if (debouncedSearch)         params.q        = debouncedSearch;
        return params;
      };

      if (viewMode === "user") {
        if (!selectedUserId) return;
        await api.superadmin.exportUserAuditLogs(selectedUserId, buildParams(1));
      } else {
        if (!orgId) return;
        const first = await api.organizations.getAuditLogs(orgId, buildParams(1));
        const allLogs = [...(first.audit_logs ?? [])];
        const totalPages = first.pages ?? 1;

        if (totalPages > 1) {
          const remaining = await Promise.all(
            Array.from({ length: totalPages - 1 }, (_, i) =>
              api.organizations.getAuditLogs(orgId, buildParams(i + 2))
            )
          );
          for (const r of remaining) allLogs.push(...(r.audit_logs ?? []));
        }

        const esc = (v: string) => `"${v.replace(/"/g, '""')}"`;
        const header = ["ID","Action","Description","User Email","User ID","Resource Type","Resource ID","IP Address","User Agent","Success","Error Message","Created At","Updated At"];
        const rows = allLogs.map((l) => [
          l.id, l.action, l.description ?? "",
          l.user?.email ?? "", l.user_id ?? "",
          l.resource_type ?? "", l.resource_id ?? "",
          l.ip_address ?? "", l.user_agent ?? "",
          l.success ? "Yes" : "No",
          l.error_message ?? "",
          l.created_at, l.updated_at ?? "",
        ].map(esc).join(","));
        const csv = [header.map(esc).join(","), ...rows].join("\n");

        const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = `audit-logs-${new Date().toISOString().slice(0, 10)}.csv`;
        a.click();
        URL.revokeObjectURL(url);
      }
    } catch (err) {
      console.error("Export failed:", err);
    } finally {
      setIsExporting(false);
    }
  }, [orgId, viewMode, selectedUserId, actionFilter, successFilter, userFilter, debouncedSearch]);

  return (
    <div className="page-container">
      {/* Header */}
      <div className="page-header flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
        <div>
          <h1 className="page-title">Admin Audit Log</h1>
          <p className="page-description">
            {viewMode === "user"
              ? `User events for ${selectedUserLabel ?? "selected user"}`
              : "Organisation activity — user events, admin actions, policy changes"
            }
            {totalCount > 0 && ` · ${totalCount.toLocaleString()} total`}
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Button variant="outline" size="sm" onClick={handleExport} disabled={isExporting || isLoading}>
            <Download className="w-4 h-4 mr-2" />
            {isExporting ? "Exporting…" : "Export CSV"}
          </Button>
          <Button variant="outline" size="sm" onClick={fetchLogs} disabled={isLoading}>
            <RefreshCw className={`w-4 h-4 mr-2 ${isLoading ? "animate-spin" : ""}`} />
            Refresh
          </Button>
        </div>
      </div>

      {/* View mode toggle */}
      <div className="flex items-center gap-1 p-1 bg-muted rounded-lg w-fit mb-4">
        <Button variant={viewMode === "org" ? "default" : "ghost"} size="sm" onClick={() => setViewMode("org")}>
          Org events
        </Button>
        <Button variant={viewMode === "user" ? "default" : "ghost"} size="sm" onClick={() => setViewMode("user")}>
          User events
        </Button>
      </div>

      {/* User selector (user mode only) */}
      {viewMode === "user" && (
        <div className="flex gap-3 mb-4">
          <Select
            value={selectedUserId ?? ""}
            onValueChange={(v) => {
              const member = orgMembers.find((m) => m.user_id === v);
              setSelectedUserId(v);
              setSelectedUserLabel(member?.user?.email ?? member?.user?.full_name ?? `${v.slice(0, 8)}…`);
            }}
          >
            <SelectTrigger className="w-[320px]">
              <Globe className="w-4 h-4 mr-2" />
              <SelectValue placeholder={isMembersLoading ? "Loading users…" : "Select a user…"} />
            </SelectTrigger>
            <SelectContent>
              {orgMembers.map((m) => (
                <SelectItem key={m.user_id} value={m.user_id}>
                  {m.user?.email || m.user?.full_name || m.user_id.slice(0, 8)}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      )}

      {/* Filters */}
      <div className="flex flex-col sm:flex-row gap-3 mb-4">
        <div className="relative flex-1">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
          <Input
            placeholder="Search descriptions…"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="pl-10"
          />
        </div>
        <Select value={actionFilter} onValueChange={setActionFilter}>
          <SelectTrigger className="w-[210px]">
            <Filter className="w-4 h-4 mr-2" />
            <SelectValue placeholder="Filter by action" />
          </SelectTrigger>
          <SelectContent>
            {ACTION_FILTER_OPTIONS.map((o) => (
              <SelectItem key={o.value} value={o.value}>{o.label}</SelectItem>
            ))}
          </SelectContent>
        </Select>
        <Select value={successFilter} onValueChange={setSuccessFilter}>
          <SelectTrigger className="w-[150px]">
            <SelectValue placeholder="Status" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All statuses</SelectItem>
            <SelectItem value="true">Success only</SelectItem>
            <SelectItem value="false">Failures only</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {/* Active filter chips */}
      {(actionFilter !== "all" || successFilter !== "all" || userFilter) && (
        <div className="flex flex-wrap items-center gap-2 mb-4">
          {actionFilter !== "all" && (
            <Badge variant="secondary" className="gap-1 px-3 py-1">
              <span className="text-xs">Action: {ACTION_CHIP_LABELS[actionFilter] ?? actionFilter}</span>
              <X
                className="w-3 h-3 cursor-pointer hover:text-destructive"
                onClick={() => setActionFilter("all")}
              />
            </Badge>
          )}
          {userFilter && (
            <Badge variant="secondary" className="gap-1 px-3 py-1">
              <span className="text-xs">User: {userFilterLabel ?? userFilter.slice(0, 8) + "…"}</span>
              <X
                className="w-3 h-3 cursor-pointer hover:text-destructive"
                onClick={() => { setUserFilter(null); setUserFilterLabel(null); }}
              />
            </Badge>
          )}
          {successFilter !== "all" && (
            <Badge variant="secondary" className="gap-1 px-3 py-1">
              <span className="text-xs">Status: {successFilter === "true" ? "Success only" : "Failures only"}</span>
              <X
                className="w-3 h-3 cursor-pointer hover:text-destructive"
                onClick={() => setSuccessFilter("all")}
              />
            </Badge>
          )}
        </div>
      )}

      {/* Table */}
      <Card>
        <CardContent className="p-0">
          {isLoading ? (
            <div className="flex items-center justify-center py-16">
              <Loader2 className="w-6 h-6 animate-spin text-muted-foreground" />
              <span className="ml-2 text-muted-foreground">Loading…</span>
            </div>
          ) : accessDenied ? (
            <div className="py-16 text-center text-muted-foreground">
              <Lock className="w-10 h-10 mx-auto mb-3 text-muted-foreground/50" />
              <p className="font-medium text-base">Access Restricted</p>
              <p className="text-sm mt-1 max-w-sm mx-auto">
                You don't have permission to view user audit logs. Contact your administrator to request access.
              </p>
            </div>
          ) : error ? (
            <div className="py-12 text-center text-destructive">
              <AlertTriangle className="w-8 h-8 mx-auto mb-2" />
              <p>{error}</p>
            </div>
          ) : viewMode === "user" && !selectedUserId ? (
            <div className="py-16 text-center text-muted-foreground">
              <UserCog className="w-10 h-10 mx-auto mb-3 text-muted-foreground/50" />
              <p className="font-medium text-base">No user selected</p>
              <p className="text-sm mt-1">Select a user above to view their audit events.</p>
            </div>
          ) : auditLogs.length === 0 ? (
            <div className="py-12 text-center text-muted-foreground">
              No audit events match the current filters.
            </div>
          ) : (
            <div className="divide-y">
              {auditLogs.map((log) => {
                const cat = getCategory(log.action);
                const meta = CATEGORY_META[cat];
                const isCert = log.action.startsWith("ssh.cert");
                return (
                  <div key={log.id} className="flex items-start gap-4 px-4 py-3 hover:bg-muted/30 transition-colors">
                    {/* Icon */}
                    <div
                      className={`mt-0.5 w-9 h-9 rounded-lg flex items-center justify-center flex-shrink-0 ${
                        log.success ? meta.color : "bg-destructive/10 text-destructive"
                      }`}
                    >
                      {log.success ? getCategoryIcon(cat) : <XCircle className="w-4 h-4" />}
                    </div>

                    {/* Body */}
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-2 flex-wrap">
                        <span
                          className="font-medium text-sm text-foreground cursor-pointer hover:text-primary transition-colors"
                          onClick={() =>
                            setActionFilter((prev) => (prev === log.action ? "all" : log.action))
                          }
                        >
                          {getActionLabel(log.action)}
                        </span>
                        <Badge variant="secondary" className={`text-xs px-1.5 py-0 ${meta.color}`}>
                          {meta.label}
                        </Badge>
                        {!log.success && (
                          <Badge variant="destructive" className="text-xs px-1.5 py-0">Failed</Badge>
                        )}
                      </div>

                      {/* Description */}
                      {log.description && (
                        <p className="mt-0.5 text-sm text-muted-foreground">
                          {log.description}
                          {isCert && <CertDetail metadata={log.metadata} />}
                        </p>
                      )}
                      {log.error_message && (
                        <p className="mt-0.5 text-xs text-destructive">{log.error_message}</p>
                      )}

                      {/* Actor / meta row */}
                      <div className="mt-1 flex flex-wrap items-center gap-x-3 gap-y-0.5 text-xs text-muted-foreground">
                        {log.user?.email ? (
                          <span
                            className="font-medium text-foreground/70 cursor-pointer hover:text-foreground transition-colors"
                            onClick={() => {
                              if (log.user_id) {
                                setUserFilter((prev) => (prev === log.user_id ? null : log.user_id));
                                setUserFilterLabel((prev) => (prev === log.user.email ? null : log.user.email));
                              }
                            }}
                          >{log.user.email}</span>
                        ) : log.user_id ? (
                          <span
                            className="font-mono cursor-pointer hover:text-foreground transition-colors"
                            onClick={() => {
                              setUserFilter((prev) => (prev === log.user_id ? null : log.user_id));
                              setUserFilterLabel((prev) => prev === log.user_id ? null : `${log.user_id!.slice(0, 8)}…`);
                            }}
                          >{log.user_id.slice(0, 8)}…</span>
                        ) : (
                          <span className="italic">System</span>
                        )}
                        {log.ip_address && (
                          <span className="font-mono">{log.ip_address}</span>
                        )}
                        {log.resource_type && (
                          <Badge variant="outline" className="text-xs px-1.5 py-0 font-mono">
                            {log.resource_type}
                          </Badge>
                        )}
                      </div>
                    </div>

                    {/* Timestamp */}
                    <div className="flex flex-col items-end gap-1 flex-shrink-0">
                      <p className="text-xs text-muted-foreground whitespace-nowrap">
                        {formatDateTime(log.created_at)}
                      </p>
                      {log.success ? (
                        <CheckCircle2 className="w-3.5 h-3.5 text-emerald-500" />
                      ) : (
                        <XCircle className="w-3.5 h-3.5 text-destructive" />
                      )}
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Pagination */}
      {totalPages > 1 && (
        <div className="flex items-center justify-between mt-4">
          <p className="text-sm text-muted-foreground">
            Page {page} of {totalPages} &nbsp;·&nbsp; {totalCount.toLocaleString()} events
          </p>
          <div className="flex items-center gap-2">
            <Button
              variant="outline" size="sm"
              disabled={page <= 1 || isLoading}
              onClick={() => setPage((p) => p - 1)}
            >
              <ChevronLeft className="w-4 h-4" /> Prev
            </Button>
            <Button
              variant="outline" size="sm"
              disabled={page >= totalPages || isLoading}
              onClick={() => setPage((p) => p + 1)}
            >
              Next <ChevronRight className="w-4 h-4" />
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}