import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import axios from "axios";
import { useTranslation } from "react-i18next";

import {
  createRecordCollaboratorComment,
  deleteRecordCollaboratorComment,
  getMyRecordCollaboratorComments,
  listRecordCollaboratorComments,
  RecordCollaboratorCommentDto,
  updateRecordCollaboratorComment,
} from "@/record-management/services/api/recordCollaboratorCommentsService";
import { useErrorHandler } from "@/shared/hooks/useErrorHandler";

interface UseRecordCollaboratorCommentsOptions {
  recordId?: string;
  contentId?: string;
  collaborationId?: string;
  enabled?: boolean;
}

interface AggregatedCollaboratorComments {
  comments: RecordCollaboratorCommentDto[];
  myComment: RecordCollaboratorCommentDto | null;
}

const sortComments = (items: RecordCollaboratorCommentDto[]) =>
  [...items].sort((a, b) => {
    const left = new Date(a.updatedAt || a.createdAt).getTime();
    const right = new Date(b.updatedAt || b.createdAt).getTime();
    return right - left;
  });

export const useRecordCollaboratorComments = ({
  recordId,
  contentId,
  collaborationId,
  enabled = true,
}: UseRecordCollaboratorCommentsOptions) => {
  const queryClient = useQueryClient();
  const { t } = useTranslation();
  const { handleError } = useErrorHandler(t);

  const commentsQuery = useQuery<AggregatedCollaboratorComments>({
    queryKey: [
      "record-collaborator-comments",
      recordId,
      contentId,
      collaborationId,
    ],
    enabled: enabled && Boolean(recordId) && Boolean(contentId),
    queryFn: async () => {
      const commentsResponse = await listRecordCollaboratorComments(
        contentId as string,
        {
          skip: 0,
          take: 100,
          // order: "createdAt:DESC",
        },
      );

      const myComments = collaborationId
        ? await getMyRecordCollaboratorComments(collaborationId)
        : [];

      const versionFilteredComments = contentId
        ? commentsResponse.items.filter(
            (comment) => comment.recordContentId === contentId,
          )
        : commentsResponse.items;
      const versionFilteredMyComments = contentId
        ? myComments.filter((comment) => comment.recordContentId === contentId)
        : myComments;

      return {
        comments: sortComments(versionFilteredComments),
        myComment: versionFilteredMyComments[0] ?? null,
      };
    },
    staleTime: 0,
    refetchOnMount: true,
    refetchOnWindowFocus: true,
    refetchOnReconnect: true,
  });

  const invalidateComments = async () => {
    await queryClient.invalidateQueries({
      queryKey: [
        "record-collaborator-comments",
        recordId,
        contentId,
        collaborationId,
      ],
    });
  };

  const createMutation = useMutation({
    mutationFn: createRecordCollaboratorComment,
    onSuccess: invalidateComments,
    onError: async (error) => {
      if (axios.isAxiosError(error) && error.response?.status === 409) {
        await handleError({
          response: {
            status: 409,
            data: {
              message: t(
                "collaboration.commentExists",
                "You have already commented on this record version.",
              ),
            },
          },
        });
        return;
      }

      await handleError(error);
    },
  });

  const updateMutation = useMutation({
    mutationFn: ({ id, comment }: { id: string; comment: string }) =>
      updateRecordCollaboratorComment(id, { comment }),
    onSuccess: invalidateComments,
    onError: async (error) => {
      await handleError(error);
    },
  });

  const deleteMutation = useMutation({
    mutationFn: deleteRecordCollaboratorComment,
    onSuccess: invalidateComments,
    onError: async (error) => {
      await handleError(error);
    },
  });

  return {
    ...commentsQuery,
    comments: commentsQuery.data?.comments ?? [],
    myComment: commentsQuery.data?.myComment ?? null,
    createComment: createMutation.mutateAsync,
    updateComment: updateMutation.mutateAsync,
    deleteComment: deleteMutation.mutateAsync,
    isCreatingComment: createMutation.isPending,
    isUpdatingComment: updateMutation.isPending,
    isDeletingComment: deleteMutation.isPending,
  };
};
