import { useServerSuspenseQuery } from "@/lib/tanstack-query/hooks";
import { listPlayers, getPlayer, getUnassociatedPlayers, fetchMe, getPlayerStats, getAllPlayerStats, getPlayerMatches, getUnenrolledPlayers, getPlayersActivity } from "./server";
import { logger } from '@/lib/supertokens';

let queryRefreshRedirect: Promise<void> | null = null;

export const playerKeys = {
  auth: ['auth'],
  list: ['players', 'list'],
  details: (id: string) => ['players', 'details', id],
  unassociated: ['players','unassociated'],
  unenrolled: (tournamentId: string) => ['players', 'unenrolled', tournamentId],
  stats: (id: string, viewType?: 'all' | 'mainline' | 'regional') => ['players', 'stats', id, viewType ?? 'all'],
  allStats: (viewType?: 'all' | 'mainline' | 'regional') => ['players', 'stats', 'all', viewType ?? 'all'],
  matches: (id: string) => ['players', 'matches', id],
  activity: ['players', 'activity'],
};

export const playerQueries = {
  auth: () => ({
    queryKey: playerKeys.auth,
    queryFn: async () => await fetchMe()
  }),
  list: () => ({
    queryKey: playerKeys.list,
    queryFn: async () => await listPlayers()
  }),
  details: (id: string) => ({
    queryKey: playerKeys.details(id),
    queryFn: async () => await getPlayer({ data: id })
  }),
  unassociated: () => ({
    queryKey: playerKeys.unassociated,
    queryFn: async () => await getUnassociatedPlayers()
  }),
  unenrolled: (tournamentId: string) => ({
    queryKey: playerKeys.unenrolled(tournamentId),
    queryFn: async () => await getUnenrolledPlayers({ data: tournamentId })
  }),
  stats: (id: string, viewType?: 'all' | 'mainline' | 'regional') => ({
    queryKey: playerKeys.stats(id, viewType),
    queryFn: async () => await getPlayerStats({ data: { playerId: id, viewType } })
  }),
  allStats: (viewType?: 'all' | 'mainline' | 'regional') => ({
    queryKey: playerKeys.allStats(viewType),
    queryFn: async () => await getAllPlayerStats({ data: viewType })
  }),
  matches: (id: string) => ({
    queryKey: playerKeys.matches(id),
    queryFn: async () => await getPlayerMatches({ data: id })
  }),
  activity: () => ({
    queryKey: playerKeys.activity,
    queryFn: async () => await getPlayersActivity()
  }),
};

export const useMe = () => {
  const { queryKey, queryFn } = playerQueries.auth();
  return useServerSuspenseQuery({
    queryKey,
    queryFn,
    options: {
      staleTime: 30 * 1000,
      refetchOnMount: false,
      refetchOnWindowFocus: true,
      retry: (failureCount, error: any) => {
        if (error?.response?.status === 401) {
          const errorData = error?.response?.data;
          if (errorData?.error === 'SESSION_REFRESH_REQUIRED') {
            logger.warn("Query detected SESSION_REFRESH_REQUIRED");

            if (!queryRefreshRedirect) {
              const currentUrl = window.location.pathname + window.location.search;
              logger.info("Query initiating refresh redirect to:", currentUrl);

              queryRefreshRedirect = new Promise<void>((resolve) => {
                setTimeout(() => {
                  window.location.href = `/refresh-session?redirect=${encodeURIComponent(currentUrl)}`;
                  resolve();
                }, 100);
              });

              queryRefreshRedirect.finally(() => {
                setTimeout(() => {
                  queryRefreshRedirect = null;
                }, 1000);
              });
            } else {
              logger.info("Query: refresh redirect already in progress");
            }

            return false;
          }
        }
        return failureCount < 3;
      },
    },
  });
};

export const usePlayer = (id: string) =>
  useServerSuspenseQuery(playerQueries.details(id));

export const usePlayers = () => 
  useServerSuspenseQuery(playerQueries.list());

export const useUnassociatedPlayers = () => 
  useServerSuspenseQuery(playerQueries.unassociated());

export const usePlayerStats = (id: string, viewType?: 'all' | 'mainline' | 'regional') =>
  useServerSuspenseQuery(playerQueries.stats(id, viewType));

export const useAllPlayerStats = (viewType?: 'all' | 'mainline' | 'regional') =>
  useServerSuspenseQuery(playerQueries.allStats(viewType));

export const usePlayerMatches = (id: string) =>
  useServerSuspenseQuery(playerQueries.matches(id));

export const useUnenrolledPlayers = (tournamentId: string) =>
  useServerSuspenseQuery(playerQueries.unenrolled(tournamentId));

export const usePlayersActivity = () =>
  useServerSuspenseQuery(playerQueries.activity());