import { logger } from "@/lib/logger"; import type { Tournament, TournamentInfo, TournamentInput, TournamentUpdateInput, } from "@/features/tournaments/types"; import type { Team } from "@/features/teams/types"; import PocketBase from "pocketbase"; import { transformFreeAgent, transformTournament, transformTournamentInfo } from "@/lib/pocketbase/util/transform-types"; import { transformTeam } from "@/lib/pocketbase/util/transform-types"; import { PlayerInfo } from "@/features/players/types"; export function createTournamentsService(pb: PocketBase) { return { async getTournament(id: string, isAdmin: boolean = false): Promise { const [tournamentResult, teamStatsResult] = await Promise.all([ pb.collection("tournaments").getOne(id, { expand: "teams, teams.players, matches, matches.tournament, matches.home, matches.away, matches.home.players, matches.away.players", }), pb.collection("team_stats_per_tournament").getFullList({ filter: `tournament_id = "${id}"`, sort: "-wins,-total_cups_made" }) ]); tournamentResult.team_stats = teamStatsResult; return transformTournament(tournamentResult, isAdmin); }, async getMostRecentTournament(): Promise { const result = await pb .collection("tournaments") .getFirstListItem('', { expand: "teams, teams.players, matches, matches.tournament, matches.home, matches.away, matches.home.players, matches.away.players", sort: "-start_time", } ); const teamStatsResult = await pb.collection("team_stats_per_tournament").getFullList({ filter: `tournament_id = "${result.id}"`, sort: "-wins,-total_cups_made" }); result.team_stats = teamStatsResult; return transformTournament(result); }, async listTournaments(): Promise { const result = await pb .collection("tournaments") .getFullList({ expand: "teams,teams.players,matches", sort: "-start_time", }); const tournamentsWithStats = await Promise.all(result.map(async (tournament) => { const teamStats = await pb.collection("team_stats_per_tournament").getFullList({ filter: `tournament_id = "${tournament.id}"`, sort: "-wins,-total_cups_made" }); tournament.team_stats = teamStats; return tournament; })); return tournamentsWithStats.map(transformTournamentInfo); }, async createTournament(data: TournamentInput): Promise { const result = await pb .collection("tournaments") .create(data); return transformTournament(result); }, async updateTournament( id: string, data: Partial ): Promise { const result = await pb .collection("tournaments") .update(id, data); return transformTournament(result); }, async enrollTeam( tournamentId: string, teamId: string ): Promise { const result = await pb .collection("tournaments") .update( tournamentId, { "teams+": teamId }, { expand: "teams, teams.players" } ); await pb .collection("teams") .update(teamId, { "tournaments+": tournamentId }); return transformTournament(result); }, async unenrollTeam( tournamentId: string, teamId: string ): Promise { const result = await pb .collection("tournaments") .update( tournamentId, { "teams-": teamId }, { expand: "teams, teams.players" } ); await pb .collection("teams") .update(teamId, { "tournaments-": tournamentId }); return transformTournament(result); }, async updateTournamentMatches( tournamentId: string, matchIds: string[] ): Promise { logger.info("PocketBase | Updating tournament matches", { tournamentId, matchCount: matchIds.length }); const result = await pb .collection("tournaments") .update(tournamentId, { matches: matchIds }); return transformTournament(result); }, async getUnenrolledTeams(tournamentId: string): Promise { try { const tournament = await pb .collection("tournaments") .getOne(tournamentId, { fields: "teams", }); const enrolledTeamIds = tournament.teams || []; if (enrolledTeamIds.length === 0) { const allTeams = await pb.collection("teams").getFullList({ expand: "players", }); return allTeams.map(transformTeam); } const filter = enrolledTeamIds .map((teamId: string) => `id != "${teamId}"`) .join(" && "); const availableTeams = await pb.collection("teams").getFullList({ filter, expand: "players", }); return availableTeams.map(transformTeam); } catch (error) { logger.error("PocketBase | Error getting unenrolled teams", error); throw error; } }, async enrollFreeAgent(playerId: string, phone: string, tournamentId: string): Promise { await pb.collection("free_agents").create({ tournament: tournamentId, player: playerId, phone: phone }); }, async unenrollFreeAgent(playerId: string, tournamentId: string): Promise { const result = await pb.collection("free_agents").getFirstListItem( `player = "${playerId}" && tournament = "${tournamentId}"` ); await pb.collection("free_agents").delete(result.id); }, async getFreeAgents(tournamentId: string): Promise<{ id: string, phone: string, player: PlayerInfo | undefined }[]> { try { const free_agents = await pb .collection("free_agents") .getFullList({ filter: `tournament = "${tournamentId}"`, expand: 'player' }); return free_agents.map(transformFreeAgent); } catch (error) { logger.error("PocketBase | Error getting unenrolled teams", error); throw error; } }, }; }