import { superTokensAdminFunctionMiddleware, superTokensFunctionMiddleware } from "@/utils/supertokens";
import { createServerFn } from "@tanstack/react-start";
import { pbAdmin } from "@/lib/pocketbase/client";
import { tournamentInputSchema } from "@/features/tournaments/types";
import { logger } from ".";
import { z } from "zod";
import { toServerResult } from "@/lib/tanstack-query/utils/to-server-result";
import { serverFnLoggingMiddleware } from "@/utils/activities";
import { fa } from "zod/v4/locales";

export const listTournaments = createServerFn()
  .middleware([superTokensFunctionMiddleware])
  .handler(async () => 
    toServerResult(pbAdmin.listTournaments)
  );

export const createTournament = createServerFn()
  .inputValidator(tournamentInputSchema)
  .middleware([superTokensAdminFunctionMiddleware, serverFnLoggingMiddleware])
  .handler(async ({ data }) => 
    toServerResult(() => pbAdmin.createTournament(data))
  );

export const updateTournament = createServerFn()
  .inputValidator(z.object({
    id: z.string(),
    updates: tournamentInputSchema.partial()
  }))
  .middleware([superTokensAdminFunctionMiddleware, serverFnLoggingMiddleware])
  .handler(async ({ data }) => 
    toServerResult(() => pbAdmin.updateTournament(data.id, data.updates))
  );

export const getTournament = createServerFn()
  .inputValidator(z.string())
  .middleware([superTokensFunctionMiddleware])
  .handler(async ({ data: tournamentId, context }) => {
    const isAdmin = context.roles.includes("Admin");
    return toServerResult(() => pbAdmin.getTournament(tournamentId, isAdmin));
  });

export const getCurrentTournament = createServerFn()
  .handler(async () => 
    toServerResult(() => pbAdmin.getMostRecentTournament())
  );

export const enrollTeam = createServerFn()
  .inputValidator(z.object({
    tournamentId: z.string(),
    teamId: z.string()
  }))
  .middleware([superTokensFunctionMiddleware, serverFnLoggingMiddleware])
  .handler(async ({ data: { tournamentId, teamId }, context }) => 
    toServerResult(async () => {
      const userId = context.userAuthId;
      const isAdmin = context.roles.includes("Admin"); 

      const team = await pbAdmin.getTeam(teamId);
      if (!team) { throw new Error('Team not found'); }

      //const isPlayerOnTeam = team.players?.some(player => player.id === userId);

      //if (!isPlayerOnTeam && !isAdmin) {
      //  throw new Error('You do not have permission to enroll this team');
      //}

      const freeAgents = await pbAdmin.getFreeAgents(tournamentId);
      for (const player of team.players || []) {
        const isFreeAgent = freeAgents.some(fa => fa.player?.id === player.id);
        if (isFreeAgent) {
          await pbAdmin.unenrollFreeAgent(player.id, tournamentId);
        }
      }

      logger.info('Enrolling team in tournament', { tournamentId, teamId, userId });
      const tournament = await pbAdmin.enrollTeam(tournamentId, teamId);
      return tournament;
    })
  );

export const unenrollTeam = createServerFn()
  .inputValidator(z.object({
    tournamentId: z.string(),
    teamId: z.string()
  }))
  .middleware([superTokensFunctionMiddleware, serverFnLoggingMiddleware])
  .handler(async ({ data: { tournamentId, teamId }, context }) => 
    toServerResult(() => pbAdmin.unenrollTeam(tournamentId, teamId))
  );

export const getUnenrolledTeams = createServerFn()
  .inputValidator(z.string())
  .middleware([superTokensAdminFunctionMiddleware])
  .handler(async ({ data: tournamentId }) => 
    toServerResult(() => pbAdmin.getUnenrolledTeams(tournamentId))
  );

export const getFreeAgents = createServerFn()
  .inputValidator(z.string())
  .middleware([superTokensFunctionMiddleware])
  .handler(async ({ data: tournamentId }) => 
    toServerResult(() => pbAdmin.getFreeAgents(tournamentId))
  );

export const enrollFreeAgent = createServerFn()
  .inputValidator(z.object({ phone: z.string(), tournamentId: z.string() }))
  .middleware([superTokensFunctionMiddleware, serverFnLoggingMiddleware])
  .handler(async ({ context, data }) =>
    toServerResult(async () => {
      const userAuthId = context.userAuthId;
      const player = await pbAdmin.getPlayerByAuthId(userAuthId);
      if (!player) throw new Error("Player not found");

      await pbAdmin.enrollFreeAgent(player.id, data.phone, data.tournamentId);
      logger.info('Player enrolled as free agent', { playerId: player.id, phone: data.phone });
    })
  );

export const unenrollFreeAgent = createServerFn()
  .inputValidator(z.object({ tournamentId: z.string() }))
  .middleware([superTokensFunctionMiddleware, serverFnLoggingMiddleware])
  .handler(async ({ context, data }) =>
    toServerResult(async () => {
      const userAuthId = context.userAuthId;
      const player = await pbAdmin.getPlayerByAuthId(userAuthId);
      if (!player) throw new Error("Player not found");

      await pbAdmin.unenrollFreeAgent(player.id, data.tournamentId);
      logger.info('Player unenrolled as free agent', { playerId: player.id });
    })
  );
