"use client";

import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { Check, Loader2, Mail, X } from "lucide-react";

import { useTRPC } from "@karakeep/shared-react/trpc";

interface Invitation {
  id: string;
  role: string;
  list: {
    name: string;
    icon?: string;
    description?: string | null;
    owner?: {
      name?: string;
    } | null;
  };
}

function InvitationRow({ invitation }: { invitation: Invitation }) {
  const api = useTRPC();
  const { t } = useTranslation();
  const queryClient = useQueryClient();

  const acceptInvitation = useMutation(
    api.lists.acceptInvitation.mutationOptions({
      onSuccess: async () => {
        toast({
          description: t("lists.invitations.accepted"),
        });
        await Promise.all([
          queryClient.invalidateQueries(
            api.lists.getPendingInvitations.pathFilter(),
          ),
          queryClient.invalidateQueries(api.lists.list.pathFilter()),
        ]);
      },
      onError: (error) => {
        toast({
          variant: "destructive",
          description: error.message || t("lists.invitations.failed_to_accept"),
        });
      },
    }),
  );

  const declineInvitation = useMutation(
    api.lists.declineInvitation.mutationOptions({
      onSuccess: async () => {
        toast({
          description: t("lists.invitations.declined"),
        });
        await queryClient.invalidateQueries(
          api.lists.getPendingInvitations.pathFilter(),
        );
      },
      onError: (error) => {
        toast({
          variant: "destructive",
          description:
            error.message || t("lists.invitations.failed_to_decline"),
        });
      },
    }),
  );

  return (
    <div className="flex items-center justify-between rounded-lg border p-4">
      <div className="flex-1">
        <div className="flex items-center gap-2">
          <span className="font-medium">{invitation.list.name}</span>
          <span className="text-xs text-muted-foreground">
            {invitation.list.icon}
          </span>
        </div>
        {invitation.list.description && (
          <div className="mt-1 text-sm text-muted-foreground">
            {invitation.list.description}
          </div>
        )}
        <div className="mt-2 text-sm text-muted-foreground">
          {t("lists.invitations.invited_by")}{" "}
          <span className="font-medium">
            {invitation.list.owner?.name || "Unknown"}
          </span>
          {" • "}
          <span className="capitalize">{invitation.role}</span>
        </div>
      </div>
      <div className="flex items-center gap-2">
        <Button
          size="sm"
          variant="outline"
          onClick={() =>
            declineInvitation.mutate({ invitationId: invitation.id })
          }
          disabled={declineInvitation.isPending || acceptInvitation.isPending}
        >
          {declineInvitation.isPending ? (
            <Loader2 className="h-4 w-4 animate-spin" />
          ) : (
            <>
              <X className="mr-1 h-4 w-4" />
              {t("lists.invitations.decline")}
            </>
          )}
        </Button>
        <Button
          size="sm"
          onClick={() =>
            acceptInvitation.mutate({ invitationId: invitation.id })
          }
          disabled={acceptInvitation.isPending || declineInvitation.isPending}
        >
          {acceptInvitation.isPending ? (
            <Loader2 className="h-4 w-4 animate-spin" />
          ) : (
            <>
              <Check className="mr-1 h-4 w-4" />
              {t("lists.invitations.accept")}
            </>
          )}
        </Button>
      </div>
    </div>
  );
}

export function PendingInvitationsCard() {
  const api = useTRPC();
  const { t } = useTranslation();

  const { data: invitations, isLoading } = useQuery(
    api.lists.getPendingInvitations.queryOptions(),
  );

  if (isLoading) {
    return null;
  }

  if (!invitations || invitations.length === 0) {
    return null;
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2 font-normal">
          <Mail className="h-5 w-5" />
          {t("lists.invitations.pending")}

          <span className="rounded bg-secondary p-1 text-sm text-secondary-foreground">
            {invitations.length}
          </span>
        </CardTitle>
        <CardDescription>{t("lists.invitations.description")}</CardDescription>
      </CardHeader>
      <CardContent className="space-y-3">
        {invitations.map((invitation) => (
          <InvitationRow key={invitation.id} invitation={invitation} />
        ))}
      </CardContent>
    </Card>
  );
}
