import {
  useQuery,
  useInfiniteQuery,
  QueryClient,
  useMutation,
} from "@tanstack/react-query";
import { useAuthToken } from "../hooks/use-root-data";
import { MessageList } from "../../src/api/types/models";
import { createChatApi } from "~/utils/api-client-factory";

/**
 * Custom hook to get the list of user's threads
 */
export function useGetUserThreads() {
  const token = useAuthToken();

  return useQuery({
    queryKey: ["getUserThreads"],
    queryFn: async () => {
      if (!token) {
        throw new Error("Authentication token is required");
      }
      const chatApi = createChatApi(token);
      return await chatApi.apiChatV1ThreadsList();
    },
    enabled: !!token,
    retry: 1,
    retryDelay: 3000,
    refetchOnWindowFocus: false,
    refetchInterval: 20 * 1000, // 30 seconds refetch
  });
}

/**
 * Server-side function to get thread details
 */
export async function getThreadDetails(token: string, threadId: string) {
  if (!token) {
    throw new Error("Authentication token is required");
  }

  const chatApi = createChatApi(token);
  return await chatApi.apiChatV1ThreadsRead({ threadId });
}

/**
 * Custom hook to get thread details by ID
 */
export function useGetThreadDetails(threadId: string) {
  const token = useAuthToken();

  return useQuery({
    queryKey: ["getThreadDetails", threadId],
    queryFn: async () => {
      if (!token) {
        throw new Error("Authentication token is required");
      }
      const chatApi = createChatApi(token);
      return await chatApi.apiChatV1ThreadsRead({ threadId });
    },
    enabled: !!token && !!threadId,
    retry: 1,
    retryDelay: 3000,
    refetchOnWindowFocus: false,
  });
}

export const deleteMessageFromCache = (
  queryClient: QueryClient,
  threadId: string,
  messageId: string
) => {
  queryClient.setQueryData(
    ["getThreadMessages", threadId],
    (
      oldData:
        | {
            pages: Array<{
              results: MessageList[];
              nextCursor: string | null;
            }>;
            pageParams: Array<string | undefined>;
          }
        | undefined
    ) => {
      if (!oldData) return oldData;
      return {
        ...oldData,
        pages: oldData.pages.map((page) => {
          return {
            ...page,
            results: page.results.filter((message) => message.id !== messageId),
          };
        }),
      };
    }
  );
};
export const setMessagesCache = (
  queryClient: QueryClient,
  threadId: string,
  data: MessageList
) => {
  queryClient.setQueryData(
    ["getThreadMessages", threadId],
    (
      oldData:
        | {
            pages: Array<{
              results: MessageList[];
              nextCursor: string | null;
            }>;
            pageParams: Array<string | undefined>;
          }
        | undefined
    ) => {
      if (!oldData) return oldData;
      return {
        ...oldData,
        pages: oldData.pages.map((page, index: number) => {
          if (index === 0) {
            return {
              ...page,
              results: [data, ...page.results],
            };
          }
          return page;
        }),
      };
    }
  );
};
/**
 * Custom hook to get thread messages with infinite scrolling
 */
export function useGetThreadMessages(threadId: string) {
  const token = useAuthToken();

  return useInfiniteQuery({
    queryKey: ["getThreadMessages", threadId],
    queryFn: async ({ pageParam }) => {
      if (!token) {
        throw new Error("Authentication token is required");
      }
      const chatApi = createChatApi(token);

      // Using cursor-based pagination
      const response = await chatApi.apiChatV1ThreadsMessagesList({
        threadId,
        cursor: pageParam ? String(pageParam) : undefined,
      });

      // Check if response has next cursor
      let nextCursor;
      if (response.next) {
        const nextUrlParts = response.next.split("?cursor=");
        nextCursor = nextUrlParts.length > 1 ? nextUrlParts[1] : null;
      } else {
        nextCursor = null;
      }

      const messages = response.results || [];
      // Get the ID of the last message to use as next cursor

      return {
        results: messages,
        nextCursor,
      };
    },
    initialPageParam: undefined as string | undefined,
    getNextPageParam: (lastPage) => {
      return lastPage.nextCursor || undefined;
    },
    enabled: !!token && !!threadId,
    refetchOnWindowFocus: false,
  });
}

/**
 * Custom hook to create a new chat thread
 */
export function useCreateChatThread() {
  const token = useAuthToken();
  return useMutation({
    mutationFn: async (participantId: string) => {
      if (!token) {
        throw new Error("Authentication token and user ID are required");
      }
      try {
        const chatApi = createChatApi(token);
        return await chatApi.apiChatV1ThreadsCreateCreate({
          data: {
            participantId: participantId,
          },
        });
      } catch (error) {
        console.error("Error creating chat thread:", error);
        throw error;
      }
    },
  });
}
