import { Button } from '@/components/ui/button';
import { Field, FieldLabel } from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import {
  ResponsiveDialog,
  ResponsiveDialogClose,
  ResponsiveDialogContent,
  ResponsiveDialogDescription,
  ResponsiveDialogFooter,
  ResponsiveDialogHeader,
  ResponsiveDialogTitle,
} from '@/components/ui/responsive-dialog';
import { Separator } from '@/components/ui/separator';
import { UserAvatar } from '@/components/user-avatar';
import { apiClient } from '@/lib/api-client';
import type { ComplexUsersOverview } from '@repo/api-contract';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { AlertCircle, Loader2, Mail, RotateCw, Trash2, UserPlus, UserX, Users } from 'lucide-react';
import { useEffect, useState } from 'react';

type ComplexUsersSectionProps = {
  complexId: string | null;
  canManageUsers: boolean;
};

function formatDate(value: string) {
  return new Intl.DateTimeFormat('es-AR', {
    dateStyle: 'medium',
    timeStyle: 'short',
  }).format(new Date(value));
}

function UsersSkeleton() {
  return (
    <section className="rounded-xl border bg-card p-5">
      <div className="flex items-center gap-2">
        <Users className="size-5 text-muted-foreground" />
        <h3 className="text-lg font-medium">Usuarios</h3>
      </div>
      <Separator className="my-4" />
      <p className="text-sm text-muted-foreground">Cargando usuarios...</p>
    </section>
  );
}

export function ComplexUsersSection({ complexId, canManageUsers }: ComplexUsersSectionProps) {
  const queryClient = useQueryClient();
  const [email, setEmail] = useState('');
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [successMessage, setSuccessMessage] = useState<string | null>(null);
  const [invitationToCancel, setInvitationToCancel] = useState<
    ComplexUsersOverview['invitations'][number] | null
  >(null);

  useEffect(() => {
    setEmail('');
    setErrorMessage(null);
    setSuccessMessage(null);
    setInvitationToCancel(null);
  }, [complexId]);

  const usersQuery = useQuery({
    queryKey: ['complex-users', complexId],
    enabled: Boolean(complexId),
    queryFn: () => apiClient.complexes.listUsers(complexId!),
  });

  const inviteMutation = useMutation({
    mutationFn: (payload: { email: string }) => apiClient.complexes.inviteUser(complexId!, payload),
    onSuccess: async () => {
      setEmail('');
      setErrorMessage(null);
      setSuccessMessage('Invitación enviada correctamente.');
      await queryClient.invalidateQueries({ queryKey: ['complex-users', complexId] });
    },
    onError: (error: Error) => {
      setErrorMessage(error.message || 'No pudimos enviar la invitación.');
      setSuccessMessage(null);
    },
  });

  const revokeMutation = useMutation({
    mutationFn: (userId: string) => apiClient.complexes.revokeUser(complexId!, { userId }),
    onSuccess: async () => {
      setErrorMessage(null);
      setSuccessMessage('El usuario fue desvinculado del complejo.');
      await queryClient.invalidateQueries({ queryKey: ['complex-users', complexId] });
    },
    onError: (error: Error) => {
      setErrorMessage(error.message || 'No pudimos revocar el permiso.');
      setSuccessMessage(null);
    },
  });

  const resendInvitationMutation = useMutation({
    mutationFn: (invitationId: string) =>
      apiClient.complexes.resendInvitation(complexId!, invitationId),
    onSuccess: async () => {
      setErrorMessage(null);
      setSuccessMessage('La invitación se reenvió correctamente.');
      await queryClient.invalidateQueries({ queryKey: ['complex-users', complexId] });
    },
    onError: (error: Error) => {
      setErrorMessage(error.message || 'No pudimos reenviar la invitación.');
      setSuccessMessage(null);
    },
  });

  const cancelInvitationMutation = useMutation({
    mutationFn: (invitationId: string) =>
      apiClient.complexes.cancelInvitation(complexId!, invitationId),
    onSuccess: async () => {
      setErrorMessage(null);
      setSuccessMessage('La invitación fue cancelada.');
      setInvitationToCancel(null);
      await queryClient.invalidateQueries({ queryKey: ['complex-users', complexId] });
    },
    onError: (error: Error) => {
      setErrorMessage(error.message || 'No pudimos cancelar la invitación.');
      setSuccessMessage(null);
    },
  });

  const handleInvite = async (event: React.FormEvent) => {
    event.preventDefault();
    setErrorMessage(null);
    setSuccessMessage(null);

    const trimmedEmail = email.trim();

    if (!trimmedEmail) {
      setErrorMessage('Ingresá un email.');
      return;
    }

    inviteMutation.mutate({ email: trimmedEmail });
  };

  if (!complexId) {
    return (
      <section className="rounded-xl border bg-card p-5">
        <div className="flex items-center gap-2">
          <Users className="size-5 text-muted-foreground" />
          <h3 className="text-lg font-medium">Usuarios</h3>
        </div>
        <Separator className="my-4" />
        <p className="text-sm text-muted-foreground">
          Seleccioná un complejo para ver sus usuarios.
        </p>
      </section>
    );
  }

  if (usersQuery.isLoading) {
    return <UsersSkeleton />;
  }

  if (usersQuery.isError || !usersQuery.data) {
    return (
      <section className="rounded-xl border bg-card p-5">
        <div className="flex items-center gap-2">
          <Users className="size-5 text-muted-foreground" />
          <h3 className="text-lg font-medium">Usuarios</h3>
        </div>
        <Separator className="my-4" />
        <p className="text-sm text-destructive">No se pudieron cargar los usuarios del complejo.</p>
      </section>
    );
  }

  const data: ComplexUsersOverview = usersQuery.data;

  return (
    <section className="rounded-xl border bg-card p-5">
      <div className="flex items-center gap-2">
        <Users className="size-5 text-muted-foreground" />
        <h3 className="text-lg font-medium">Usuarios</h3>
      </div>
      <Separator className="my-4" />

      {canManageUsers ? (
        <form className="mb-6 rounded-lg border bg-muted/30 p-4" onSubmit={handleInvite}>
          <div className="mb-3 flex items-center gap-2">
            <UserPlus className="size-4 text-muted-foreground" />
            <h4 className="text-sm font-medium">Invitar un usuario</h4>
          </div>

          <div className="flex flex-col gap-3 sm:flex-row">
            <Field className="flex-1">
              <FieldLabel htmlFor="invite-email">Email</FieldLabel>
              <Input
                id="invite-email"
                type="email"
                value={email}
                onChange={(event) => setEmail(event.target.value)}
                placeholder="empleado@correo.com"
              />
            </Field>

            <div className="flex items-end">
              <Button type="submit" disabled={inviteMutation.isPending}>
                {inviteMutation.isPending && <Loader2 className="mr-2 size-4 animate-spin" />}
                Enviar invitación
              </Button>
            </div>
          </div>

          <p className="mt-2 text-xs text-muted-foreground">
            La invitación se envía por email y el usuario quedará vinculado como EMPLOYEE al
            aceptar.
          </p>
        </form>
      ) : (
        <div className="mb-6 rounded-lg border border-dashed p-4 text-sm text-muted-foreground">
          Solo un ADMIN puede invitar o desvincular usuarios.
        </div>
      )}

      {successMessage && (
        <p className="mb-4 text-sm text-green-600 dark:text-green-400">{successMessage}</p>
      )}
      {errorMessage && (
        <p className="mb-4 flex items-center gap-2 text-sm text-destructive">
          <AlertCircle className="size-4" />
          {errorMessage}
        </p>
      )}

      <div className="space-y-6">
        <div>
          <h4 className="mb-3 text-sm font-medium">Miembros</h4>
          <div className="space-y-2">
            {data.members.map((member) => (
              <div
                key={member.userId}
                className="flex flex-col gap-3 rounded-lg border px-4 py-3 sm:flex-row sm:items-center sm:justify-between"
              >
                <div>
                  <p className="font-medium">{member.fullName}</p>
                  <p className="text-sm text-muted-foreground">{member.email}</p>
                  <p className="text-xs text-muted-foreground">
                    Rol: {member.role} · Desde {formatDate(member.createdAt)}
                  </p>
                </div>

                <div className="flex items-center gap-2">
                  <UserAvatar
                    src={member.avatarUrl}
                    alt={member.fullName}
                    fallbackText={member.fullName}
                    size="default"
                    className="border"
                  />

                  {canManageUsers && member.role === 'EMPLOYEE' && (
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      onClick={() => revokeMutation.mutate(member.userId)}
                      disabled={revokeMutation.isPending}
                    >
                      <UserX className="mr-2 size-4" />
                      Revocar
                    </Button>
                  )}
                </div>
              </div>
            ))}
          </div>
        </div>

        <div>
          <h4 className="mb-3 text-sm font-medium">Invitaciones pendientes</h4>
          {data.invitations.length === 0 ? (
            <p className="text-sm text-muted-foreground">No hay invitaciones pendientes.</p>
          ) : (
            <div className="space-y-2">
              {data.invitations.map((invitation) => (
                <div
                  key={invitation.id}
                  className="flex flex-col gap-2 rounded-lg border px-4 py-3 sm:flex-row sm:items-center sm:justify-between"
                >
                  <div>
                    <p className="font-medium">{invitation.email}</p>
                    <p className="text-xs text-muted-foreground">
                      Vence {formatDate(invitation.expiresAt)}
                    </p>
                  </div>
                  <div className="flex flex-col items-start gap-2 sm:items-end">
                    <span className="inline-flex items-center gap-2 text-xs uppercase tracking-wide text-muted-foreground">
                      <Mail className="size-3.5" />
                      Pendiente
                    </span>

                    {canManageUsers && (
                      <div className="flex flex-wrap gap-2">
                        <Button
                          type="button"
                          variant="outline"
                          size="sm"
                          onClick={() => resendInvitationMutation.mutate(invitation.id)}
                          disabled={resendInvitationMutation.isPending}
                        >
                          <RotateCw className="mr-2 size-4" />
                          Reenviar
                        </Button>
                        <Button
                          type="button"
                          variant="destructive"
                          size="sm"
                          onClick={() => setInvitationToCancel(invitation)}
                          disabled={cancelInvitationMutation.isPending}
                        >
                          <Trash2 className="mr-2 size-4" />
                          Cancelar
                        </Button>
                      </div>
                    )}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      <ResponsiveDialog
        open={Boolean(invitationToCancel)}
        onOpenChange={(open) => {
          if (!open) {
            setInvitationToCancel(null);
          }
        }}
      >
        <ResponsiveDialogContent className="data-[variant=dialog]:max-w-md">
          <ResponsiveDialogHeader>
            <ResponsiveDialogTitle>Cancelar invitación</ResponsiveDialogTitle>
            <ResponsiveDialogDescription>
              Esta acción va a invalidar el link de invitación y la persona ya no podrá aceptar la
              invitación.
            </ResponsiveDialogDescription>
          </ResponsiveDialogHeader>

          <p className="text-sm text-muted-foreground">
            {invitationToCancel
              ? `Se cancelará la invitación enviada a ${invitationToCancel.email}.`
              : 'Se cancelará la invitación seleccionada.'}
          </p>

          <p className="text-sm text-muted-foreground">
            Si querés volver a invitarlo, vas a poder generar una nueva invitación después.
          </p>

          <ResponsiveDialogFooter>
            <ResponsiveDialogClose asChild>
              <Button variant="outline">Volver</Button>
            </ResponsiveDialogClose>
            <Button
              variant="destructive"
              onClick={() => {
                if (!invitationToCancel) return;
                cancelInvitationMutation.mutate(invitationToCancel.id);
              }}
              disabled={cancelInvitationMutation.isPending}
            >
              {cancelInvitationMutation.isPending ? 'Cancelando...' : 'Cancelar invitación'}
            </Button>
          </ResponsiveDialogFooter>
        </ResponsiveDialogContent>
      </ResponsiveDialog>
    </section>
  );
}
