import { useState } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Crown, Trash2, Loader2 } from 'lucide-react';
import { useClient } from 'hooks/useClient';
import { Button } from '@/components/ui/button';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';

type ManagedUser = {
  id: number;
  email: string;
  name: string | null;
  username: string | null;
  status: string;
  role: string;
  createdAt: string;
  isOwner: boolean;
};

type UsersResponse = { users: ManagedUser[]; roles: string[]; ownerId: number };

const USERS_KEY = ['MANAGED_USERS'];

export const UsersSection = () => {
  const client = useClient();
  const queryClient = useQueryClient();
  const [pendingId, setPendingId] = useState<number | null>(null);
  const [confirmDelete, setConfirmDelete] = useState<ManagedUser | null>(null);

  const { data, isLoading, isError } = useQuery<UsersResponse>({
    queryKey: USERS_KEY,
    queryFn: () => client.get<UsersResponse>('/users'),
  });

  const changeRole = async (user: ManagedUser, role: string) => {
    if (role === user.role) return;
    setPendingId(user.id);
    try {
      await client.patch(`/users/${user.id}/role`, { role });
      await queryClient.invalidateQueries({ queryKey: USERS_KEY });
      toast.success(`${user.email} is now ${role}`);
    } catch (ex) {
      toast.error(ex instanceof Error ? ex.message : 'Could not change the role');
    } finally {
      setPendingId(null);
    }
  };

  const remove = async (user: ManagedUser) => {
    setPendingId(user.id);
    setConfirmDelete(null);
    try {
      await client.delete(`/users/${user.id}`);
      await queryClient.invalidateQueries({ queryKey: USERS_KEY });
      toast.success(`${user.email} removed`);
    } catch (ex) {
      toast.error(ex instanceof Error ? ex.message : 'Could not remove the account');
    } finally {
      setPendingId(null);
    }
  };

  if (isLoading) {
    return (
      <div className="flex items-center gap-2 text-sm text-muted-foreground">
        <Loader2 className="h-4 w-4 animate-spin" /> Loading accounts…
      </div>
    );
  }

  if (isError || !data) {
    return <div className="text-sm text-destructive">Could not load the accounts.</div>;
  }

  return (
    <div className="space-y-4">
      <p className="text-sm text-muted-foreground">
        Every account on this server. The owner is fixed — the database itself refuses to demote or remove it — so that
        row cannot be changed from here.
      </p>

      <div className="rounded-lg border divide-y">
        {data.users.map((user) => {
          const busy = pendingId === user.id;
          return (
            <div key={user.id} className="flex items-center gap-3 p-3">
              <div className="min-w-0 flex-1">
                <div className="flex items-center gap-1.5">
                  <span className="truncate text-sm font-medium">{user.name || user.username || user.email}</span>
                  {user.isOwner && <Crown className="h-3.5 w-3.5 shrink-0 text-duck-teal" aria-label="Server owner" />}
                </div>
                <div className="truncate text-xs text-muted-foreground">
                  {user.email}
                  {user.status !== 'Active' && ` · ${user.status}`}
                </div>
              </div>

              <Select
                value={user.role}
                disabled={user.isOwner || busy}
                onValueChange={(role) => void changeRole(user, role)}
              >
                <SelectTrigger className="w-40 shrink-0">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {data.roles.map((role) => (
                    <SelectItem key={role} value={role}>
                      {role}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>

              <Button
                variant="ghost"
                size="icon"
                className="shrink-0 text-muted-foreground hover:text-destructive"
                disabled={user.isOwner || busy}
                onClick={() => setConfirmDelete(user)}
                aria-label={`Remove ${user.email}`}
              >
                {busy ? <Loader2 className="h-4 w-4 animate-spin" /> : <Trash2 className="h-4 w-4" />}
              </Button>
            </div>
          );
        })}
      </div>

      {/* Removal cascades — passkeys, dashboards, screens, email accounts, playlists — and there is no
          undo, so it is worth one deliberate confirmation. */}
      <AlertDialog open={!!confirmDelete} onOpenChange={(open) => !open && setConfirmDelete(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Remove {confirmDelete?.email}?</AlertDialogTitle>
            <AlertDialogDescription>
              This deletes the account and everything belonging to it — passkeys, dashboards, saved layouts, email
              accounts and playlists. It cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
              onClick={() => confirmDelete && void remove(confirmDelete)}
            >
              Remove account
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
};
