import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { AdminLayout } from '@/features/admin/admin-layout';
import { ApiClientError, apiClient } from '@/lib/api-client';
import type { AdminUser, AdminUserSession } from '@repo/api-contract';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useLocation } from '@tanstack/react-router';
import {
  Ban,
  CheckCircle2,
  Globe,
  LogIn,
  MapPin,
  Monitor,
  RefreshCw,
  Search,
  ShieldAlert,
  Users,
} from 'lucide-react';
import { useEffect, useState } from 'react';

function SessionsDialog({
  user,
  onClose,
}: {
  user: AdminUser;
  onClose: () => void;
}) {
  const queryClient = useQueryClient();
  const { data, isLoading } = useQuery({
    queryKey: ['admin-user-sessions', user.id],
    queryFn: () => apiClient.admin.getUserSessions(user.id),
  });

  const revokeMutation = useMutation({
    mutationFn: () => apiClient.admin.revokeAllSessions(user.id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['admin-user-sessions', user.id] });
      queryClient.invalidateQueries({ queryKey: ['admin-users'] });
    },
  });

  return (
    <Dialog open onOpenChange={(open) => !open && onClose()}>
      <DialogContent className="rounded-2xl sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>Sesiones de {user.name}</DialogTitle>
          <DialogDescription>{data?.length ?? 0} sesiones activas</DialogDescription>
        </DialogHeader>

        <div className="max-h-80 space-y-3 overflow-y-auto">
          {isLoading ? (
            <p className="py-8 text-center text-sm text-muted-foreground">Cargando sesiones...</p>
          ) : data?.length === 0 ? (
            <p className="py-8 text-center text-sm text-muted-foreground">Sin sesiones activas.</p>
          ) : (
            data?.map((session) => <SessionRow key={session.id} session={session} />)
          )}
        </div>

        <div className="flex items-center justify-between gap-3">
          {revokeMutation.error && (
            <p className="flex-1 text-sm text-destructive">
              {revokeMutation.error instanceof ApiClientError
                ? String(revokeMutation.error.details ?? revokeMutation.error.message)
                : revokeMutation.error.message}
            </p>
          )}
          <div className="flex gap-3">
            <Button variant="outline" className="rounded-xl" onClick={onClose}>
              Cerrar
            </Button>
            {data && data.length > 0 && (
              <Button
                variant="destructive"
                className="rounded-xl"
                onClick={() => revokeMutation.mutate()}
                disabled={revokeMutation.isPending}
              >
                {revokeMutation.isPending ? 'Cerrando...' : 'Cerrar todas las sesiones'}
              </Button>
            )}
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}

function SessionRow({ session }: { session: AdminUserSession }) {
  const isExpired = new Date(session.expiresAt) < new Date();
  const userAgent = session.userAgent ?? 'Desconocido';
  const ip = session.ipAddress ?? '—';
  const location =
    session.city || session.country
      ? [session.city, session.country].filter(Boolean).join(', ')
      : null;

  return (
    <div className="rounded-xl border border-border/60 p-4">
      <div className="mb-2 flex items-center gap-2">
        <Monitor className="size-4 text-muted-foreground" />
        <span className="flex-1 truncate text-sm font-medium">{userAgent}</span>
        {isExpired ? (
          <Badge
            variant="outline"
            className="border-gray-300 bg-gray-50 text-gray-600 dark:border-gray-700 dark:bg-gray-950 dark:text-gray-400"
          >
            Expirada
          </Badge>
        ) : (
          <Badge
            variant="outline"
            className="border-emerald-300 bg-emerald-50 text-emerald-700 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400"
          >
            Activa
          </Badge>
        )}
      </div>
      <div className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-muted-foreground">
        <span className="flex items-center gap-1">
          <Globe className="size-3" />
          {ip}
        </span>
        {location && (
          <span className="flex items-center gap-1">
            <MapPin className="size-3" />
            {location}
          </span>
        )}
        <span className="flex items-center gap-1">
          <LogIn className="size-3" />
          {new Date(session.createdAt).toLocaleString()}
        </span>
      </div>
    </div>
  );
}

function BlockDialog({
  user,
  onClose,
}: {
  user: AdminUser;
  onClose: () => void;
}) {
  const queryClient = useQueryClient();
  const [reason, setReason] = useState('');

  const mutation = useMutation({
    mutationFn: (banReason?: string) => apiClient.admin.blockUser(user.id, { banReason }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['admin-users'] });
      onClose();
    },
  });

  return (
    <Dialog open onOpenChange={(open) => !open && onClose()}>
      <DialogContent className="rounded-2xl sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Bloquear usuario</DialogTitle>
          <DialogDescription>
            ¿Estás seguro de bloquear a <strong>{user.name}</strong> ({user.email})? No podrá
            iniciar sesión en Playzer.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="reason">Motivo (opcional)</Label>
            <Input
              id="reason"
              value={reason}
              onChange={(e) => setReason(e.target.value)}
              placeholder="Violación de términos..."
              maxLength={500}
            />
          </div>

          {mutation.error && (
            <p className="text-sm text-destructive">
              {mutation.error instanceof ApiClientError
                ? String(mutation.error.details ?? mutation.error.message)
                : mutation.error.message}
            </p>
          )}

          <div className="flex justify-end gap-3">
            <Button type="button" variant="outline" className="rounded-xl" onClick={onClose}>
              Cancelar
            </Button>
            <Button
              type="button"
              variant="destructive"
              className="rounded-xl"
              onClick={() => mutation.mutate(reason || undefined)}
              disabled={mutation.isPending}
            >
              {mutation.isPending ? 'Bloqueando...' : 'Bloquear'}
            </Button>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}

function UnblockDialog({
  user,
  onClose,
}: {
  user: AdminUser;
  onClose: () => void;
}) {
  const queryClient = useQueryClient();

  const mutation = useMutation({
    mutationFn: () => apiClient.admin.unblockUser(user.id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['admin-users'] });
      onClose();
    },
  });

  return (
    <Dialog open onOpenChange={(open) => !open && onClose()}>
      <DialogContent className="rounded-2xl sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Desbloquear usuario</DialogTitle>
          <DialogDescription>
            ¿Estás seguro de desbloquear a <strong>{user.name}</strong>? Podrá volver a iniciar
            sesión en Playzer.
          </DialogDescription>
        </DialogHeader>

        {mutation.error && (
          <p className="text-sm text-destructive">
            {mutation.error instanceof ApiClientError
              ? String(mutation.error.details ?? mutation.error.message)
              : mutation.error.message}
          </p>
        )}

        <div className="flex justify-end gap-3">
          <Button type="button" variant="outline" className="rounded-xl" onClick={onClose}>
            Cancelar
          </Button>
          <Button
            type="button"
            variant="default"
            className="rounded-xl"
            onClick={() => mutation.mutate()}
            disabled={mutation.isPending}
          >
            {mutation.isPending ? 'Desbloqueando...' : 'Desbloquear'}
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}

function RoleBadge({ role }: { role: string }) {
  if (role === 'super_admin') {
    return (
      <Badge
        variant="outline"
        className="border-purple-300 bg-purple-50 text-purple-700 dark:border-purple-700 dark:bg-purple-950 dark:text-purple-400"
      >
        <ShieldAlert className="mr-1 size-3" />
        Super Admin
      </Badge>
    );
  }

  return (
    <Badge variant="secondary" className="text-xs">
      {role}
    </Badge>
  );
}

export function UsersPage() {
  const location = useLocation();
  const queryClient = useQueryClient();
  const [blockingUser, setBlockingUser] = useState<AdminUser | null>(null);
  const [unblockingUser, setUnblockingUser] = useState<AdminUser | null>(null);
  const [sessionsUser, setSessionsUser] = useState<AdminUser | null>(null);
  const [searchInput, setSearchInput] = useState('');
  const [search, setSearch] = useState('');

  useEffect(() => {
    const timer = setTimeout(() => setSearch(searchInput), 300);
    return () => clearTimeout(timer);
  }, [searchInput]);

  const { data, isLoading } = useQuery({
    queryKey: ['admin-users', search],
    queryFn: () => apiClient.admin.listUsers(search || undefined),
  });

  return (
    <AdminLayout currentPath={location.pathname}>
      <div className="mb-6 flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">Usuarios</h1>
          <p className="mt-1 text-sm text-muted-foreground">
            {data?.length ?? 0} usuarios registrados en Playzer.
          </p>
        </div>

        <div className="flex items-center gap-2">
          <div className="relative">
            <Search className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
            <Input
              value={searchInput}
              onChange={(e) => setSearchInput(e.target.value)}
              placeholder="Buscar por nombre o email..."
              className="h-9 w-56 rounded-xl pl-9 text-sm"
            />
          </div>
          <Button
            variant="outline"
            size="icon"
            className="rounded-xl"
            onClick={() => queryClient.invalidateQueries({ queryKey: ['admin-users'] })}
          >
            <RefreshCw className="size-4" />
          </Button>
        </div>
      </div>

      {blockingUser && <BlockDialog user={blockingUser} onClose={() => setBlockingUser(null)} />}

      {unblockingUser && (
        <UnblockDialog user={unblockingUser} onClose={() => setUnblockingUser(null)} />
      )}

      {sessionsUser && <SessionsDialog user={sessionsUser} onClose={() => setSessionsUser(null)} />}

      {isLoading ? (
        <div className="flex items-center justify-center py-20">
          <p className="text-sm text-muted-foreground">Cargando usuarios...</p>
        </div>
      ) : data?.length === 0 ? (
        <div className="flex flex-col items-center justify-center py-20">
          <Users className="mb-3 size-10 text-muted-foreground/50" />
          <p className="text-sm text-muted-foreground">No hay usuarios registrados.</p>
        </div>
      ) : (
        <div className="overflow-hidden rounded-2xl border border-border/60">
          <table className="w-full">
            <thead>
              <tr className="border-b border-border/60 bg-muted/50">
                <th className="px-5 py-3 text-left text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                  Usuario
                </th>
                <th className="hidden px-5 py-3 text-left text-xs font-semibold uppercase tracking-wider text-muted-foreground md:table-cell">
                  Rol
                </th>
                <th className="hidden px-5 py-3 text-center text-xs font-semibold uppercase tracking-wider text-muted-foreground sm:table-cell">
                  Complejos
                </th>
                <th className="hidden px-5 py-3 text-center text-xs font-semibold uppercase tracking-wider text-muted-foreground lg:table-cell">
                  Sesiones
                </th>
                <th className="hidden px-5 py-3 text-center text-xs font-semibold uppercase tracking-wider text-muted-foreground lg:table-cell">
                  Registro
                </th>
                <th className="px-5 py-3 text-center text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                  Estado
                </th>
                <th className="px-5 py-3 text-right text-xs font-semibold uppercase tracking-wider text-muted-foreground">
                  Acción
                </th>
              </tr>
            </thead>
            <tbody className="divide-y divide-border/40">
              {data?.map((user) => (
                <tr key={user.id} className="transition-colors hover:bg-accent/30">
                  <td className="px-5 py-4">
                    <div className="min-w-0">
                      <p className="truncate font-medium">{user.name}</p>
                      <p className="truncate text-xs text-muted-foreground">{user.email}</p>
                    </div>
                  </td>
                  <td className="hidden px-5 py-4 md:table-cell">
                    <RoleBadge role={user.role} />
                  </td>
                  <td className="hidden px-5 py-4 text-center text-sm text-muted-foreground sm:table-cell">
                    {user.complexCount}
                  </td>
                  <td className="hidden px-5 py-4 text-center lg:table-cell">
                    <button
                      type="button"
                      className="cursor-pointer text-sm font-medium text-emerald-600 underline-offset-2 hover:underline"
                      onClick={() => setSessionsUser(user)}
                    >
                      {user.activeSessions}
                    </button>
                  </td>
                  <td className="hidden px-5 py-4 text-sm text-muted-foreground lg:table-cell">
                    {new Date(user.createdAt).toLocaleDateString()}
                  </td>
                  <td className="px-5 py-4 text-center">
                    {user.banned ? (
                      <Badge
                        variant="outline"
                        className="border-red-300 bg-red-50 text-red-700 dark:border-red-700 dark:bg-red-950 dark:text-red-400"
                      >
                        Bloqueado
                      </Badge>
                    ) : (
                      <Badge
                        variant="outline"
                        className="border-emerald-300 bg-emerald-50 text-emerald-700 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400"
                      >
                        Activo
                      </Badge>
                    )}
                  </td>
                  <td className="px-5 py-4 text-right">
                    <div className="flex items-center justify-end gap-1">
                      {user.banned ? (
                        <Button
                          variant="ghost"
                          size="sm"
                          className="rounded-xl text-xs"
                          disabled={user.role === 'super_admin'}
                          onClick={() => setUnblockingUser(user)}
                        >
                          <CheckCircle2 className="mr-1.5 size-3.5 text-emerald-600" />
                          Desbloquear
                        </Button>
                      ) : (
                        <Button
                          variant="ghost"
                          size="sm"
                          className="rounded-xl text-xs text-destructive hover:bg-destructive/10 hover:text-destructive disabled:opacity-40"
                          disabled={user.role === 'super_admin'}
                          onClick={() => setBlockingUser(user)}
                        >
                          <Ban className="mr-1.5 size-3.5" />
                          Bloquear
                        </Button>
                      )}
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </AdminLayout>
  );
}
