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",
    schema: { type: "array", items: { type: "object" } },
  })
  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" })
  @ApiResponse({
    status: 200,
    description: "Country details",
    schema: { type: "object" },
  })
  @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" })
  @ApiResponse({
    status: 200,
    description: "List of leagues",
    schema: { type: "array", items: { type: "object" } },
  })
  @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" })
  @ApiResponse({
    status: 200,
    description: "Head-to-head matches",
    schema: { type: "array", items: { type: "object" } },
  })
  @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" })
  @ApiResponse({
    status: 200,
    description: "List of teams matching search",
    schema: { type: "array", items: { type: "object" } },
  })
  @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" })
  @ApiResponse({
    status: 200,
    description: "Team details",
    schema: { type: "object" },
  })
  @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)" })
  @ApiResponse({
    status: 200,
    description: "Paginated list of matches",
    schema: {
      type: "object",
      properties: {
        data: { type: "array", items: { type: "object" } },
        meta: { type: "object" },
      },
    },
  })
  @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" })
  @ApiResponse({
    status: 200,
    description: "League details",
    schema: { type: "object" },
  })
  @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;
  }
}
