import { Controller, Get, Param, Query, NotFoundException, } from "@nestjs/common"; import { ApiTags, ApiOperation, ApiResponse, ApiQuery, ApiParam, } from "@nestjs/swagger"; import { LeaguesService } from "./leagues.service"; import { Sport } from "@prisma/client"; import { Public } from "../../common/decorators"; @ApiTags("Leagues") @Controller("leagues") export class LeaguesController { constructor(private readonly leaguesService: LeaguesService) {} /** * GET /leagues/countries * Get all countries */ @Get("countries") @Public() @ApiOperation({ summary: "Get all countries" }) @ApiResponse({ status: 200, description: "List of countries" }) async getCountries() { return this.leaguesService.findAllCountries(); } /** * GET /leagues/countries/:id * Get country by ID with leagues */ @Get("countries/:id") @Public() @ApiOperation({ summary: "Get country by ID with leagues" }) @ApiParam({ name: "id", description: "Country ID" }) async getCountryById(@Param("id") id: string) { const country = await this.leaguesService.findCountryById(id); if (!country) throw new NotFoundException("Country not found"); return country; } /** * GET /leagues * Get all leagues */ @Get() @Public() @ApiOperation({ summary: "Get all leagues" }) @ApiQuery({ name: "sport", required: false, enum: ["football", "basketball"], }) async getLeagues(@Query("sport") sport?: string) { return this.leaguesService.findAllLeagues(sport as Sport); } /** * GET /leagues/teams/h2h * Get head-to-head matches between two teams * NOTE: Must come before /teams/:id to avoid route conflict */ @Get("teams/h2h") @Public() @ApiOperation({ summary: "Get head-to-head matches between two teams" }) @ApiQuery({ name: "team1", required: true }) @ApiQuery({ name: "team2", required: true }) @ApiQuery({ name: "limit", required: false, type: Number }) async getHeadToHead( @Query("team1") team1: string, @Query("team2") team2: string, @Query("limit") limit?: string, ) { return this.leaguesService.getHeadToHead( team1, team2, parseInt(limit || "10", 10), ); } /** * GET /leagues/teams/search * Search teams by name */ @Get("teams/search") @Public() @ApiOperation({ summary: "Search teams by name" }) @ApiQuery({ name: "q", required: true, description: "Search query" }) @ApiQuery({ name: "sport", required: false, enum: ["football", "basketball"], }) async searchTeams(@Query("q") query: string, @Query("sport") sport?: string) { return this.leaguesService.searchTeams(query, sport as Sport); } /** * GET /leagues/teams/:id * Get team by ID */ @Get("teams/:id") @Public() @ApiOperation({ summary: "Get team by ID" }) @ApiParam({ name: "id", description: "Team ID" }) async getTeamById(@Param("id") id: string) { const team = await this.leaguesService.findTeamById(id); if (!team) throw new NotFoundException("Team not found"); return team; } /** * GET /leagues/teams/:id/matches * Get team's recent matches (paginated) */ @Get("teams/:id/matches") @Public() @ApiOperation({ summary: "Get team's recent matches (paginated)" }) @ApiParam({ name: "id", description: "Team ID" }) @ApiQuery({ name: "page", required: false, type: Number, description: "Page number (default: 1)" }) @ApiQuery({ name: "limit", required: false, type: Number, description: "Items per page (default: 20)" }) @ApiQuery({ name: "season", required: false, type: String, description: "Season (e.g. 2024-2025)" }) async getTeamMatches( @Param("id") id: string, @Query("page") page?: string, @Query("limit") limit?: string, @Query("season") season?: string, ) { return this.leaguesService.getTeamRecentMatches( id, parseInt(page || "1", 10), parseInt(limit || "20", 10), season ); } /** * GET /leagues/:id * Get league by ID */ @Get(":id") @Public() @ApiOperation({ summary: "Get league by ID" }) @ApiParam({ name: "id", description: "League ID" }) async getLeagueById(@Param("id") id: string) { const league = await this.leaguesService.findLeagueById(id); if (!league) throw new NotFoundException("League not found"); return league; } }