import { Search, Trash2, X } from 'lucide-react';
import { toast } from 'sonner';

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

import { Badge } from '@/Components/ui/badge';
import { Button } from '@/Components/ui/button';
import { ConfirmDialog } from '@/Components/ui/confirm-dialog';
import { Input } from '@/Components/ui/input';
import { Skeleton } from '@/Components/ui/skeleton';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/Components/ui/table';
import { couldnt } from '@/lib/messages';
import type { FeatureFlagUserOverride, FeatureFlagUserSearch } from '@/types/admin';

interface ConfirmDialogState {
  open: boolean;
  title: string;
  description: string;
  onConfirm: () => void | Promise<void>;
  variant?: 'default' | 'destructive';
}

interface UserOverridesSectionProps {
  flagKey: string;
  isProtected: boolean;
  overrides: FeatureFlagUserOverride[];
  isLoading: boolean;
  onAdd: (userId: number, enabled: boolean) => Promise<void>;
  onRemove: (userId: number) => Promise<void>;
  onRemoveAll: () => Promise<void>;
}

export default function UserOverridesSection({
  flagKey,
  isProtected,
  overrides,
  isLoading,
  onAdd,
  onRemove,
  onRemoveAll,
}: UserOverridesSectionProps) {
  const [searchQuery, setSearchQuery] = useState('');
  const [searchResults, setSearchResults] = useState<FeatureFlagUserSearch[]>([]);
  const [searching, setSearching] = useState(false);
  const [confirmDialog, setConfirmDialog] = useState<ConfirmDialogState>({
    open: false,
    title: '',
    description: '',
    onConfirm: async () => {},
  });

  const searchDebounceRef = useRef<ReturnType<typeof setTimeout>>();
  useEffect(() => () => clearTimeout(searchDebounceRef.current), []);

  const executeSearch = useCallback(async (query: string) => {
    if (query.length < 2) {
      setSearchResults([]);
      return;
    }
    setSearching(true);
    try {
      const response = await fetch(
        `/admin/feature-flags/search-users?q=${encodeURIComponent(query)}`,
      );
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      const data: unknown = await response.json();
      setSearchResults(Array.isArray(data) ? (data as FeatureFlagUserSearch[]) : []);
    } catch {
      toast.error(couldnt('search', 'users'));
    } finally {
      setSearching(false);
    }
  }, []);

  const handleSearchChange = (value: string) => {
    setSearchQuery(value);
    clearTimeout(searchDebounceRef.current);
    searchDebounceRef.current = setTimeout(() => executeSearch(value), 300);
  };

  const openConfirmDialog = (config: Omit<ConfirmDialogState, 'open'>) => {
    setConfirmDialog({ ...config, open: true });
  };

  return (
    <div className="overflow-x-auto space-y-4">
      <div className="flex items-center justify-between">
        <h4 className="font-medium">User-Specific Overrides</h4>
        {overrides.length > 0 && !isProtected && (
          <Button
            variant="ghost"
            size="sm"
            onClick={() => {
              openConfirmDialog({
                title: 'Remove all user overrides',
                description: `Remove all ${overrides.length} user overrides for "${flagKey}"?`,
                variant: 'destructive',
                onConfirm: onRemoveAll,
              });
            }}
          >
            <Trash2 className="mr-2 h-4 w-4" />
            Clear all
          </Button>
        )}
      </div>

      {!isProtected && (
        <div className="relative">
          <label htmlFor={`user-search-${flagKey}`} className="sr-only">
            Search users by name or email for {flagKey}
          </label>
          <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
          <Input
            id={`user-search-${flagKey}`}
            placeholder="Search users by name or email..."
            value={searchQuery}
            onChange={(e) => handleSearchChange(e.target.value)}
            className="pl-9"
          />
          {searching && (
            <span className="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-muted-foreground">
              Searching...
            </span>
          )}
        </div>
      )}

      {searchResults.length > 0 && (
        <div className="rounded-md border">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>User</TableHead>
                <TableHead className="text-right">Add Override</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {searchResults.map((user) => (
                <TableRow key={user.id}>
                  <TableCell>
                    <div>
                      <div className="font-medium">{user.name}</div>
                      <div className="text-sm text-muted-foreground">{user.email}</div>
                    </div>
                  </TableCell>
                  <TableCell className="text-right">
                    <div className="flex justify-end gap-2">
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => {
                          openConfirmDialog({
                            title: 'Enable for user',
                            description: `Enable "${flagKey}" for ${user.name}?`,
                            onConfirm: async () => {
                              await onAdd(user.id, true);
                              setSearchQuery('');
                              setSearchResults([]);
                            },
                          });
                        }}
                      >
                        Enable
                      </Button>
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => {
                          openConfirmDialog({
                            title: 'Disable for user',
                            description: `Disable "${flagKey}" for ${user.name}?`,
                            onConfirm: async () => {
                              await onAdd(user.id, false);
                              setSearchQuery('');
                              setSearchResults([]);
                            },
                          });
                        }}
                      >
                        Disable
                      </Button>
                    </div>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>
      )}

      {isLoading ? (
        <div role="status" aria-live="polite" className="space-y-2">
          <Skeleton className="h-9 w-full" />
          <Skeleton className="h-9 w-full" />
          <Skeleton className="h-9 w-full" />
        </div>
      ) : overrides.length > 0 ? (
        <div className="rounded-md border">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>User</TableHead>
                <TableHead>Override</TableHead>
                <TableHead className="text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {overrides.map((override) => (
                <TableRow key={override.user_id}>
                  <TableCell>
                    <div>
                      <div className="font-medium">{override.name}</div>
                      <div className="text-sm text-muted-foreground">{override.email}</div>
                    </div>
                  </TableCell>
                  <TableCell>
                    <Badge variant={override.enabled ? 'success' : 'destructive'}>
                      {override.enabled ? 'ON' : 'OFF'}
                    </Badge>
                  </TableCell>
                  <TableCell className="text-right">
                    <Button
                      variant="ghost"
                      size="sm"
                      aria-label={`Remove override for ${override.name}`}
                      onClick={() => {
                        openConfirmDialog({
                          title: 'Remove override',
                          description: `Remove override for ${override.name}?`,
                          variant: 'destructive',
                          onConfirm: () => onRemove(override.user_id),
                        });
                      }}
                      disabled={isProtected}
                    >
                      <X className="h-4 w-4" />
                    </Button>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>
      ) : (
        <p className="text-sm text-muted-foreground py-4 text-center">
          No user-specific overrides for this flag.
        </p>
      )}

      <ConfirmDialog
        open={confirmDialog.open}
        onOpenChange={(open) => setConfirmDialog((prev) => ({ ...prev, open }))}
        title={confirmDialog.title}
        description={confirmDialog.description}
        variant={confirmDialog.variant}
        onConfirm={confirmDialog.onConfirm}
      />
    </div>
  );
}
