import { MoreHorizontal, Shield, Users, X } from 'lucide-react';
import { toast } from 'sonner';

import { useState, useCallback, useEffect, useRef, useMemo } from 'react';

import { Head, Link, router, usePage } from '@inertiajs/react';

import { AdminDataTable } from '@/Components/admin/AdminDataTable';
import { ChartErrorBoundary } from '@/Components/admin/ChartErrorBoundary';
import { PerPageSelector } from '@/Components/admin/PerPageSelector';
import { SortHeader } from '@/Components/admin/SortHeader';
import PageHeader from '@/Components/layout/PageHeader';
import { Badge } from '@/Components/ui/badge';
import {
  Breadcrumb,
  BreadcrumbItem,
  BreadcrumbLink,
  BreadcrumbList,
  BreadcrumbPage,
  BreadcrumbSeparator,
} from '@/Components/ui/breadcrumb';
import { Button } from '@/Components/ui/button';
import { Checkbox } from '@/Components/ui/checkbox';
import { ConfirmDialog } from '@/Components/ui/confirm-dialog';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/Components/ui/dropdown-menu';
import { ExportButton } from '@/Components/ui/export-button';
import { Input } from '@/Components/ui/input';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/Components/ui/select';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/Components/ui/table';
import { useAdminAction } from '@/hooks/useAdminAction';
import { useAdminFilters } from '@/hooks/useAdminFilters';
import { useAdminKeyboardShortcuts } from '@/hooks/useAdminKeyboardShortcuts';
import { useNavigationState } from '@/hooks/useNavigationState';
import AdminLayout from '@/Layouts/AdminLayout';
import { formatRelativeTime } from '@/lib/format';
import type { PageProps } from '@/types';
import type { AdminUsersIndexProps } from '@/types/admin';

export default function AdminUsersIndex({ users, filters }: AdminUsersIndexProps) {
  const { search, setSearch, updateFilter, handleSort, handlePage, clearFilters } = useAdminFilters(
    {
      route: '/admin/users',
      filters,
    },
  );
  const isNavigating = useNavigationState();
  const { confirmAction, setConfirmAction, executeAction, getDialogProps } = useAdminAction();
  const { auth } = usePage<PageProps>().props;
  const currentUserId = auth.user?.id;
  const canMutate = auth.user?.admin_role != null && auth.user.admin_role !== 'viewer';

  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());
  const [bulkConfirmOpen, setBulkConfirmOpen] = useState(false);
  const searchInputRef = useRef<HTMLInputElement>(null);
  const [localMinSites, setLocalMinSites] = useState(filters.min_sites ?? '');
  const minSitesTimeout = useRef<ReturnType<typeof setTimeout>>();

  const hasUsageFilters = !!(
    filters.has_gsc ||
    filters.has_wp ||
    filters.has_applied_recs ||
    filters.min_sites ||
    filters.lead_tier
  );

  useEffect(() => {
    setLocalMinSites(filters.min_sites ?? '');
  }, [filters.min_sites]);

  useEffect(() => {
    return () => clearTimeout(minSitesTimeout.current);
  }, []);

  const currentPage = users.current_page;
  const lastPage = users.last_page;
  useAdminKeyboardShortcuts({
    onSearch: () => searchInputRef.current?.focus(),
    onNextPage: currentPage < lastPage ? () => handlePage(currentPage + 1) : undefined,
    onPrevPage: currentPage > 1 ? () => handlePage(currentPage - 1) : undefined,
  });

  // Only non-admin, active, non-self users are eligible for bulk deactivation
  const selectableIds = useMemo(
    () =>
      new Set(
        users.data
          .filter((u) => !u.is_admin && !u.deleted_at && u.id !== currentUserId)
          .map((u) => u.id),
      ),
    [users.data, currentUserId],
  );
  const allSelectableSelected =
    selectableIds.size > 0 && [...selectableIds].every((id) => selectedIds.has(id));

  const toggleUser = useCallback((id: number) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  }, []);

  const toggleAll = useCallback(() => {
    if (allSelectableSelected) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(selectableIds));
    }
  }, [allSelectableSelected, selectableIds]);

  const executeBulkDeactivate = useCallback((): Promise<void> => {
    return new Promise((resolve, reject) => {
      const ids = Array.from(selectedIds);
      if (ids.length === 0) {
        resolve();
        return;
      }
      router.post(
        '/admin/users/bulk-deactivate',
        { ids },
        {
          preserveState: true,
          onSuccess: () => {
            setSelectedIds(new Set());
            setBulkConfirmOpen(false);
            toast.success(`${ids.length} user(s) deactivated.`);
            resolve();
          },
          onError: () => {
            toast.error(
              'Operation failed. Your session may have expired — refresh and try again.',
            );
            reject();
          },
        },
      );
    });
  }, [selectedIds]);

  return (
    <AdminLayout>
      <Head title="Admin - Users" />
      <div className="container pt-6">
        <Breadcrumb>
          <BreadcrumbList>
            <BreadcrumbItem>
              <BreadcrumbLink asChild>
                <Link href="/admin">Admin</Link>
              </BreadcrumbLink>
            </BreadcrumbItem>
            <BreadcrumbSeparator />
            <BreadcrumbItem>
              <BreadcrumbPage>Users</BreadcrumbPage>
            </BreadcrumbItem>
          </BreadcrumbList>
        </Breadcrumb>
      </div>
      <PageHeader
        title="Users"
        subtitle="Manage user accounts"
        actions={<ExportButton href={route('admin.users.export')} />}
      />

      <div className="container py-6 space-y-6">
        {/* Filters */}
        <fieldset className="flex flex-col sm:flex-row gap-3 sm:items-center">
          <legend className="sr-only">User Filters</legend>
          <Input
            ref={searchInputRef}
            placeholder="Search by name or email..."
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="max-w-sm"
            aria-label="Search users by name or email"
          />
          <Select
            value={filters.admin ?? 'all'}
            onValueChange={(value) => updateFilter({ admin: value === 'all' ? undefined : value })}
          >
            <SelectTrigger className="w-[180px]" aria-label="Filter by admin status">
              <SelectValue placeholder="All users" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Users</SelectItem>
              <SelectItem value="1">Admins Only</SelectItem>
              <SelectItem value="0">Non-Admins</SelectItem>
            </SelectContent>
          </Select>
          <div className="sm:ml-auto">
            <PerPageSelector
              value={filters.per_page ?? 25}
              onChange={(perPage) => updateFilter({ per_page: perPage })}
            />
          </div>
        </fieldset>

        {/* Product Usage Filters */}
        <fieldset className="flex flex-wrap items-end gap-3">
          <legend className="sr-only">Product Usage Filters</legend>
          <Select
            value={filters.has_gsc ?? 'all'}
            onValueChange={(value) =>
              updateFilter({ has_gsc: value === 'all' ? undefined : value })
            }
          >
            <SelectTrigger className="w-[170px]" aria-label="Filter by GSC connection">
              <SelectValue placeholder="GSC: All" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">GSC: All</SelectItem>
              <SelectItem value="1">GSC Connected</SelectItem>
              <SelectItem value="0">GSC Not Connected</SelectItem>
            </SelectContent>
          </Select>
          <Select
            value={filters.has_wp ?? 'all'}
            onValueChange={(value) => updateFilter({ has_wp: value === 'all' ? undefined : value })}
          >
            <SelectTrigger className="w-[170px]" aria-label="Filter by WP connection">
              <SelectValue placeholder="WP: All" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">WP: All</SelectItem>
              <SelectItem value="1">WP Connected</SelectItem>
              <SelectItem value="0">WP Not Connected</SelectItem>
            </SelectContent>
          </Select>
          <Select
            value={filters.has_applied_recs ?? 'all'}
            onValueChange={(value) =>
              updateFilter({ has_applied_recs: value === 'all' ? undefined : value })
            }
          >
            <SelectTrigger className="w-55" aria-label="Filter by applied recommendations">
              <SelectValue placeholder="Recommendations: All" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">Recommendations: All</SelectItem>
              <SelectItem value="1">Applied Recommendations</SelectItem>
              <SelectItem value="0">No Applied Recommendations</SelectItem>
            </SelectContent>
          </Select>
          <div className="flex flex-col gap-1">
            <Input
              type="number"
              min={1}
              placeholder="Min sites"
              value={localMinSites}
              onChange={(e) => {
                const val = e.target.value;
                setLocalMinSites(val);
                clearTimeout(minSitesTimeout.current);
                minSitesTimeout.current = setTimeout(() => {
                  updateFilter({ min_sites: val || undefined });
                }, 300);
              }}
              className="w-[130px]"
              aria-label="Minimum number of sites"
            />
          </div>
          <Select
            value={filters.lead_tier ?? 'all'}
            onValueChange={(value) =>
              updateFilter({ lead_tier: value === 'all' ? undefined : value })
            }
          >
            <SelectTrigger className="w-[160px]" aria-label="Filter by lead tier">
              <SelectValue placeholder="Lead Tier: All" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">Lead Tier: All</SelectItem>
              <SelectItem value="pql">PQL</SelectItem>
              <SelectItem value="hot">Hot</SelectItem>
              <SelectItem value="warm">Warm</SelectItem>
              <SelectItem value="cold">Cold</SelectItem>
            </SelectContent>
          </Select>
          {hasUsageFilters && (
            <Button
              variant="ghost"
              size="sm"
              onClick={() => {
                clearTimeout(minSitesTimeout.current);
                setLocalMinSites('');
                updateFilter({
                  has_gsc: undefined,
                  has_wp: undefined,
                  has_applied_recs: undefined,
                  min_sites: undefined,
                  lead_tier: undefined,
                });
              }}
            >
              <X className="mr-1 h-4 w-4" />
              Clear usage filters
            </Button>
          )}
        </fieldset>

        {/* Bulk Action Bar */}
        {canMutate && selectedIds.size > 0 && (
          <div
            className="flex items-center gap-3 rounded-lg border bg-muted/50 px-4 py-2"
            role="status"
            aria-live="polite"
          >
            <span className="text-sm font-medium">
              {selectedIds.size} {selectedIds.size === 1 ? 'user' : 'users'} selected
            </span>
            <Button variant="destructive" size="sm" onClick={() => setBulkConfirmOpen(true)}>
              Deactivate Selected
            </Button>
            <Button
              variant="ghost"
              size="sm"
              onClick={() => setSelectedIds(new Set())}
              aria-label="Clear selection"
            >
              <X className="mr-1 h-4 w-4" />
              Clear
            </Button>
          </div>
        )}

        <ChartErrorBoundary label="Unable to load users table">
          <AdminDataTable
            isEmpty={users.data.length === 0}
            isNavigating={isNavigating}
            isLoading={isNavigating}
            pagination={users}
            onPage={handlePage}
            paginationLabel="users"
            emptyIcon={Users}
            emptyTitle="No users found"
            emptyDescription={
              filters.search || filters.admin || hasUsageFilters
                ? 'No users match your current filters. Try adjusting your search or filter.'
                : 'User accounts will appear here once people register.'
            }
            emptyAction={
              filters.search || filters.admin || hasUsageFilters ? (
                <Button variant="outline" size="sm" onClick={clearFilters}>
                  Clear filters
                </Button>
              ) : undefined
            }
          >
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-[40px]">
                    {canMutate && (
                      <Checkbox
                        checked={allSelectableSelected && selectableIds.size > 0}
                        onCheckedChange={toggleAll}
                        aria-label="Select all users"
                        disabled={selectableIds.size === 0}
                      />
                    )}
                  </TableHead>
                  <SortHeader
                    column="name"
                    label="Name"
                    currentSort={filters.sort}
                    currentDir={filters.dir}
                    onSort={handleSort}
                  />
                  <SortHeader
                    column="email"
                    label="Email"
                    currentSort={filters.sort}
                    currentDir={filters.dir}
                    onSort={handleSort}
                  />
                  <TableHead>Admin</TableHead>
                  <TableHead>Verified</TableHead>
                  <SortHeader
                    column="last_login_at"
                    label="Last Login"
                    currentSort={filters.sort}
                    currentDir={filters.dir}
                    onSort={handleSort}
                  />
                  <SortHeader
                    column="created_at"
                    label="Created"
                    currentSort={filters.sort}
                    currentDir={filters.dir}
                    onSort={handleSort}
                  />
                  <TableHead>Lead</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead className="w-[50px]" />
                </TableRow>
              </TableHeader>
              <TableBody>
                {users.data.map((user) => {
                  const isSelectable = selectableIds.has(user.id);
                  return (
                    <TableRow key={user.id} data-selected={selectedIds.has(user.id) || undefined}>
                      <TableCell>
                        {canMutate && isSelectable ? (
                          <Checkbox
                            checked={selectedIds.has(user.id)}
                            onCheckedChange={() => toggleUser(user.id)}
                            aria-label={`Select ${user.name}`}
                          />
                        ) : canMutate ? (
                          <Checkbox disabled aria-label={`Cannot select ${user.name}`} />
                        ) : null}
                      </TableCell>
                      <TableCell>
                        <Link
                          href={`/admin/users/${user.id}`}
                          className="font-medium hover:underline"
                        >
                          {user.name}
                        </Link>
                      </TableCell>
                      <TableCell className="text-sm text-muted-foreground max-w-50">
                        <span className="block truncate" title={user.email}>
                          {user.email}
                        </span>
                      </TableCell>
                      <TableCell>
                        <div className="flex flex-wrap gap-1">
                          {user.is_admin ? (
                            <Badge variant="success">Admin</Badge>
                          ) : (
                            <Badge variant="secondary">User</Badge>
                          )}
                          {user.is_admin && user.admin_role && (
                            <Badge variant="outline" className="text-xs capitalize">
                              {user.admin_role.replace(/_/g, ' ')}
                            </Badge>
                          )}
                        </div>
                      </TableCell>
                      <TableCell>
                        {user.email_verified_at ? (
                          <Badge variant="secondary">Verified</Badge>
                        ) : (
                          <Badge variant="outline" className="text-muted-foreground">
                            Unverified
                          </Badge>
                        )}
                      </TableCell>
                      <TableCell className="text-sm text-muted-foreground">
                        {formatRelativeTime(user.last_login_at)}
                      </TableCell>
                      <TableCell className="text-sm text-muted-foreground">
                        {formatRelativeTime(user.created_at)}
                      </TableCell>
                      <TableCell>
                        {user.lead_score_tier ? (
                          <Badge
                            variant={
                              user.lead_score_tier === 'pql'
                                ? 'success'
                                : user.lead_score_tier === 'hot'
                                  ? 'warning'
                                  : 'secondary'
                            }
                            title={`Lead score: ${user.lead_score ?? 0}`}
                          >
                            {user.lead_score_tier.toUpperCase()}
                          </Badge>
                        ) : (
                          <span className="text-xs text-muted-foreground">—</span>
                        )}
                      </TableCell>
                      <TableCell>
                        {user.deleted_at ? (
                          <Badge variant="destructive">Deactivated</Badge>
                        ) : (
                          <Badge variant="success">Active</Badge>
                        )}
                      </TableCell>
                      <TableCell>
                        <DropdownMenu>
                          <DropdownMenuTrigger asChild>
                            <Button
                              variant="ghost"
                              size="icon"
                              className="h-8 w-8"
                              aria-label="User actions"
                            >
                              <MoreHorizontal className="h-4 w-4" />
                            </Button>
                          </DropdownMenuTrigger>
                          <DropdownMenuContent align="end">
                            <DropdownMenuItem asChild>
                              <Link href={`/admin/users/${user.id}`}>View Details</Link>
                            </DropdownMenuItem>
                            {canMutate && (
                              <>
                                <DropdownMenuSeparator />
                                <DropdownMenuItem
                                  onClick={() => setConfirmAction({ type: 'toggleAdmin', user })}
                                >
                                  <Shield className="mr-2 h-4 w-4" />
                                  {user.is_admin ? 'Remove Admin' : 'Make Admin'}
                                </DropdownMenuItem>
                                <DropdownMenuItem
                                  onClick={() => setConfirmAction({ type: 'toggleActive', user })}
                                >
                                  {user.deleted_at ? 'Restore User' : 'Deactivate User'}
                                </DropdownMenuItem>
                                {!user.is_admin && !user.deleted_at && user.id !== currentUserId && (
                                  <DropdownMenuItem
                                    onClick={() => setConfirmAction({ type: 'impersonate', user })}
                                  >
                                    Impersonate
                                  </DropdownMenuItem>
                                )}
                              </>
                            )}
                          </DropdownMenuContent>
                        </DropdownMenu>
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </AdminDataTable>
        </ChartErrorBoundary>
      </div>

      {/* Single Action Confirm Dialog */}
      <ConfirmDialog
        open={!!confirmAction}
        onOpenChange={(open) => !open && setConfirmAction(null)}
        onConfirm={executeAction}
        {...getDialogProps()}
      />

      {/* Bulk Deactivate Confirm Dialog */}
      <ConfirmDialog
        open={bulkConfirmOpen}
        onOpenChange={setBulkConfirmOpen}
        onConfirm={executeBulkDeactivate}
        title="Bulk Deactivate Users"
        description={`Are you sure you want to deactivate ${selectedIds.size} user(s)? They will not be able to log in.`}
        variant="destructive"
        confirmLabel="Deactivate"
      />
    </AdminLayout>
  );
}
