import { Body, Controller, Delete, Get, HttpCode, Param, Patch, Post, Inject, ValidationPipe, Query } from '@nestjs/common';
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Public } from '../auth/Public';
import { LeagueService } from './LeagueService';
import { AllLeaguesWithCapacityDTO } from './dtos/AllLeaguesWithCapacityDTO';
import { AllLeaguesWithCapacityAndScoringDTO } from './dtos/AllLeaguesWithCapacityAndScoringDTO';
import { ApproveJoinRequestInputDTO } from './dtos/ApproveJoinRequestInputDTO';
import { ApproveJoinRequestOutputDTO } from './dtos/ApproveJoinRequestOutputDTO';
import { CreateLeagueInputDTO } from './dtos/CreateLeagueInputDTO';
import { CreateLeagueOutputDTO } from './dtos/CreateLeagueOutputDTO';
import { GetLeagueRacesOutputDTO } from './dtos/GetLeagueRacesOutputDTO';
import { GetSeasonSponsorshipsOutputDTO } from './dtos/GetSeasonSponsorshipsOutputDTO';
import { LeagueAdminDTO } from './dtos/LeagueAdminDTO';
import { LeagueAdminPermissionsDTO } from './dtos/LeagueAdminPermissionsDTO';
import { LeagueAdminProtestsDTO } from './dtos/LeagueAdminProtestsDTO';
import { LeagueConfigFormModelDTO } from './dtos/LeagueConfigFormModelDTO';
import { LeagueJoinRequestDTO } from './dtos/LeagueJoinRequestDTO';
import { LeagueMembershipsDTO } from './dtos/LeagueMembershipsDTO';
import { LeagueRosterJoinRequestDTO } from './dtos/LeagueRosterJoinRequestDTO';
import { LeagueRosterMemberDTO } from './dtos/LeagueRosterMemberDTO';
import { LeagueOwnerSummaryDTO } from './dtos/LeagueOwnerSummaryDTO';
import { LeagueScheduleDTO } from './dtos/LeagueScheduleDTO';
import {
  LeagueSeasonSchedulePublishInputDTO,
  LeagueSeasonSchedulePublishOutputDTO,
} from './dtos/LeagueSeasonSchedulePublishDTO';
import {
  CreateLeagueScheduleRaceInputDTO,
  CreateLeagueScheduleRaceOutputDTO,
  LeagueScheduleRaceMutationSuccessDTO,
  UpdateLeagueScheduleRaceInputDTO,
} from './dtos/LeagueScheduleRaceAdminDTO';
import { LeagueSeasonSummaryDTO } from './dtos/LeagueSeasonSummaryDTO';
import { LeagueStandingsDTO } from './dtos/LeagueStandingsDTO';
import { LeagueStatsDTO } from './dtos/LeagueStatsDTO';
import { RejectJoinRequestInputDTO } from './dtos/RejectJoinRequestInputDTO';
import { RejectJoinRequestOutputDTO } from './dtos/RejectJoinRequestOutputDTO';
import { RemoveLeagueMemberOutputDTO } from './dtos/RemoveLeagueMemberOutputDTO';
import { UpdateLeagueMemberRoleInputDTO } from './dtos/UpdateLeagueMemberRoleInputDTO';
import { UpdateLeagueMemberRoleOutputDTO } from './dtos/UpdateLeagueMemberRoleOutputDTO';
import { GetLeagueOwnerSummaryQueryDTO } from './dtos/GetLeagueOwnerSummaryQueryDTO';
import { GetLeagueAdminConfigQueryDTO } from './dtos/GetLeagueAdminConfigQueryDTO';
import { GetLeagueProtestsQueryDTO } from './dtos/GetLeagueProtestsQueryDTO';
import { GetLeagueSeasonsQueryDTO } from './dtos/GetLeagueSeasonsQueryDTO';
import { GetLeagueWalletOutputDTO } from './dtos/GetLeagueWalletOutputDTO';
import { TotalLeaguesDTO } from './dtos/TotalLeaguesDTO';
import { GetLeagueScheduleQueryDTO } from './dtos/GetLeagueScheduleQueryDTO';
import { WithdrawFromLeagueWalletInputDTO } from './dtos/WithdrawFromLeagueWalletInputDTO';
import { WithdrawFromLeagueWalletOutputDTO } from './dtos/WithdrawFromLeagueWalletOutputDTO';
import { LeagueScoringPresetsDTO } from './dtos/LeagueScoringPresetsDTO';
import { TransferLeagueOwnershipInputDTO } from './dtos/TransferLeagueOwnershipInputDTO';

@ApiTags('leagues')
@Controller('leagues')
export class LeagueController {
  constructor(@Inject(LeagueService) private readonly leagueService: LeagueService) {}

  @Public()
  @Get('all-with-capacity')
  @ApiOperation({ summary: 'Get all leagues with their capacity information' })
  @ApiResponse({ status: 200, description: 'List of leagues with capacity', type: AllLeaguesWithCapacityDTO })
  async getAllLeaguesWithCapacity(): Promise<AllLeaguesWithCapacityDTO> {
    return this.leagueService.getAllLeaguesWithCapacity();
  }

  @Public()
  @Get('all-with-capacity-and-scoring')
  @ApiOperation({ summary: 'Get all leagues with capacity and scoring information' })
  @ApiResponse({ status: 200, description: 'List of leagues with capacity and scoring', type: AllLeaguesWithCapacityAndScoringDTO })
  async getAllLeaguesWithCapacityAndScoring(): Promise<AllLeaguesWithCapacityAndScoringDTO> {
    return this.leagueService.getAllLeaguesWithCapacityAndScoring();
  }

  @Public()
  @Get('total-leagues')
  @ApiOperation({ summary: 'Get the total number of leagues' })
  @ApiResponse({ status: 200, description: 'Total number of leagues', type: TotalLeaguesDTO })
  async getTotalLeagues(): Promise<TotalLeaguesDTO> {
    return this.leagueService.getTotalLeagues();
  }

  @Get(':leagueId/join-requests')
  @ApiOperation({ summary: 'Get all outstanding join requests for a league' })
  @ApiResponse({ status: 200, description: 'List of join requests', type: [LeagueJoinRequestDTO] })
  async getJoinRequests(@Param('leagueId') leagueId: string): Promise<LeagueJoinRequestDTO[]> {
    // No specific query DTO needed for GET, leagueId from param
    return this.leagueService.getLeagueJoinRequests(leagueId);
  }

  @Post(':leagueId/join-requests/approve')
  @ApiOperation({ summary: 'Approve a league join request' })
  @ApiBody({ type: ApproveJoinRequestInputDTO }) // Explicitly define body type for Swagger
  @ApiResponse({ status: 200, description: 'Join request approved', type: ApproveJoinRequestOutputDTO })
  @ApiResponse({ status: 404, description: 'Join request not found' })
  async approveJoinRequest(
    @Param('leagueId') leagueId: string,
    @Body() input: ApproveJoinRequestInputDTO,
  ): Promise<ApproveJoinRequestOutputDTO> {
    return this.leagueService.approveLeagueJoinRequest({ ...input, leagueId });
  }

  @Post(':leagueId/join-requests/reject')
  @ApiOperation({ summary: 'Reject a league join request' })
  @ApiBody({ type: RejectJoinRequestInputDTO })
  @ApiResponse({ status: 200, description: 'Join request rejected', type: RejectJoinRequestOutputDTO })
  @ApiResponse({ status: 404, description: 'Join request not found' })
  async rejectJoinRequest(
    @Param('leagueId') leagueId: string,
    @Body() input: RejectJoinRequestInputDTO,
  ): Promise<RejectJoinRequestOutputDTO> {
    return this.leagueService.rejectLeagueJoinRequest({ ...input, leagueId });
  }

  @Get(':leagueId/permissions/:performerDriverId')
  @ApiOperation({ summary: 'Get league admin permissions for a performer' })
  @ApiResponse({ status: 200, description: 'League admin permissions', type: LeagueAdminPermissionsDTO })
  async getLeagueAdminPermissions(
    @Param('leagueId') leagueId: string,
    @Param('performerDriverId') _performerDriverId: string,
  ): Promise<LeagueAdminPermissionsDTO> {
    void _performerDriverId;
    return this.leagueService.getLeagueAdminPermissions({ leagueId });
  }
  
  @Patch(':leagueId/members/:targetDriverId/remove')
  @ApiOperation({ summary: 'Remove a member from the league' })
  @ApiResponse({ status: 200, description: 'Member removed successfully', type: RemoveLeagueMemberOutputDTO })
  @ApiResponse({ status: 400, description: 'Cannot remove member' })
  @ApiResponse({ status: 404, description: 'Member not found' })
  async removeLeagueMember(
    @Param('leagueId') leagueId: string,
    @Param('targetDriverId') targetDriverId: string,
  ): Promise<RemoveLeagueMemberOutputDTO> {
    return this.leagueService.removeLeagueMember({ leagueId, targetDriverId });
  }

  @Patch(':leagueId/members/:targetDriverId/role')
  @ApiOperation({ summary: "Update a member's role in the league" })
  @ApiBody({ type: UpdateLeagueMemberRoleInputDTO }) // Explicitly define body type for Swagger
  @ApiResponse({ status: 200, description: 'Member role updated successfully', type: UpdateLeagueMemberRoleOutputDTO })
  @ApiResponse({ status: 400, description: 'Cannot update role' })
  @ApiResponse({ status: 404, description: 'Member not found' })
  async updateLeagueMemberRole(
    @Param('leagueId') leagueId: string,
    @Param('targetDriverId') targetDriverId: string,
    @Body() input: UpdateLeagueMemberRoleInputDTO, // Body includes newRole, other for swagger
  ): Promise<UpdateLeagueMemberRoleOutputDTO> {
    return this.leagueService.updateLeagueMemberRole(leagueId, targetDriverId, input);
  }

  @Public()
  @Get(':leagueId/owner-summary/:ownerId')
  @ApiOperation({ summary: 'Get owner summary for a league' })
  @ApiResponse({ status: 200, description: 'League owner summary', type: LeagueOwnerSummaryDTO })
  @ApiResponse({ status: 404, description: 'Owner or league not found' })
  async getLeagueOwnerSummary(
    @Param('leagueId') leagueId: string,
    @Param('ownerId') ownerId: string,
  ): Promise<LeagueOwnerSummaryDTO | null> {
    const query: GetLeagueOwnerSummaryQueryDTO = { ownerId, leagueId };
    return this.leagueService.getLeagueOwnerSummary(query);
  }

  @Get(':leagueId/config')
   @ApiOperation({ summary: 'Get league full configuration' })
   @ApiResponse({ status: 200, description: 'League configuration form model', type: LeagueConfigFormModelDTO })
   async getLeagueFullConfig(
     @Param('leagueId') leagueId: string,
   ): Promise<LeagueConfigFormModelDTO | null> {
     const query: GetLeagueAdminConfigQueryDTO = { leagueId };
     return this.leagueService.getLeagueFullConfig(query);
   }

  @Get(':leagueId/protests')
   @ApiOperation({ summary: 'Get protests for a league' })
   @ApiResponse({ status: 200, description: 'List of protests for the league', type: LeagueAdminProtestsDTO })
   async getLeagueProtests(@Param('leagueId') leagueId: string): Promise<LeagueAdminProtestsDTO> {
     const query: GetLeagueProtestsQueryDTO = { leagueId };
     return this.leagueService.getLeagueProtests(query);
   }

  @Get(':leagueId/protests/:protestId')
  @ApiOperation({ summary: 'Get a specific protest for a league' })
  @ApiResponse({ status: 200, description: 'Protest details', type: LeagueAdminProtestsDTO })
  async getLeagueProtest(
    @Param('leagueId') leagueId: string,
    @Param('protestId') protestId: string,
  ): Promise<LeagueAdminProtestsDTO> {
    const query: GetLeagueProtestsQueryDTO = { leagueId };
    const allProtests = await this.leagueService.getLeagueProtests(query);

    // Filter to only include the specific protest
    const protest = allProtests.protests.find(p => p.id === protestId);
    if (!protest) {
      throw new Error('Protest not found');
    }

    // Find the race for this protest
    const race = allProtests.racesById[protest.raceId];
    const protestingDriver = allProtests.driversById[protest.protestingDriverId];
    const accusedDriver = allProtests.driversById[protest.accusedDriverId];

    return {
      protests: [protest],
      racesById: race ? { [race.id]: race } : {},
      driversById: {
        ...(protestingDriver ? { [protestingDriver.id]: protestingDriver } : {}),
        ...(accusedDriver ? { [accusedDriver.id]: accusedDriver } : {}),
      },
    };
  }

  @Public()
  @Get(':leagueId/seasons')
   @ApiOperation({ summary: 'Get seasons for a league' })
   @ApiResponse({ status: 200, description: 'List of seasons for the league', type: [LeagueSeasonSummaryDTO] })
   async getLeagueSeasons(@Param('leagueId') leagueId: string): Promise<LeagueSeasonSummaryDTO[]> {
     const query: GetLeagueSeasonsQueryDTO = { leagueId };
     return this.leagueService.getLeagueSeasons(query);
   }

  @Public()
  @Get(':leagueId/memberships')
  @ApiOperation({ summary: 'Get league memberships' })
  @ApiResponse({ status: 200, description: 'List of league members', type: LeagueMembershipsDTO })
  async getLeagueMemberships(@Param('leagueId') leagueId: string): Promise<LeagueMembershipsDTO> {
    return this.leagueService.getLeagueMemberships(leagueId);
  }

  @Public()
  @Get(':leagueId/standings')
  @ApiOperation({ summary: 'Get league standings' })
  @ApiResponse({ status: 200, description: 'League standings', type: LeagueStandingsDTO })
  async getLeagueStandings(@Param('leagueId') leagueId: string): Promise<LeagueStandingsDTO> {
    return this.leagueService.getLeagueStandings(leagueId);
  }

  @Public()
  @Get(':leagueId/schedule')
  @ApiOperation({ summary: 'Get league schedule' })
  @ApiResponse({ status: 200, description: 'League schedule', type: LeagueScheduleDTO })
  async getLeagueSchedule(
    @Param('leagueId') leagueId: string,
    @Query() query: GetLeagueScheduleQueryDTO,
  ): Promise<LeagueScheduleDTO> {
    return this.leagueService.getLeagueSchedule(leagueId, query);
  }

  @Post(':leagueId/seasons/:seasonId/schedule/publish')
  @HttpCode(200)
  @ApiOperation({ summary: 'Publish a league season schedule (admin/owner only; actor derived from session)' })
  @ApiBody({ type: LeagueSeasonSchedulePublishInputDTO })
  @ApiResponse({ status: 200, description: 'Schedule published', type: LeagueSeasonSchedulePublishOutputDTO })
  async publishLeagueSeasonSchedule(
    @Param('leagueId') leagueId: string,
    @Param('seasonId') seasonId: string,
    @Body(
      new ValidationPipe({
        whitelist: true,
        forbidNonWhitelisted: true,
        transform: true,
        expectedType: LeagueSeasonSchedulePublishInputDTO,
      }),
    )
    input: LeagueSeasonSchedulePublishInputDTO,
  ): Promise<LeagueSeasonSchedulePublishOutputDTO> {
    return this.leagueService.publishLeagueSeasonSchedule(leagueId, seasonId, input);
  }

  @Post(':leagueId/seasons/:seasonId/schedule/unpublish')
  @HttpCode(200)
  @ApiOperation({ summary: 'Unpublish a league season schedule (admin/owner only; actor derived from session)' })
  @ApiBody({ type: LeagueSeasonSchedulePublishInputDTO })
  @ApiResponse({ status: 200, description: 'Schedule unpublished', type: LeagueSeasonSchedulePublishOutputDTO })
  async unpublishLeagueSeasonSchedule(
    @Param('leagueId') leagueId: string,
    @Param('seasonId') seasonId: string,
    @Body(
      new ValidationPipe({
        whitelist: true,
        forbidNonWhitelisted: true,
        transform: true,
        expectedType: LeagueSeasonSchedulePublishInputDTO,
      }),
    )
    input: LeagueSeasonSchedulePublishInputDTO,
  ): Promise<LeagueSeasonSchedulePublishOutputDTO> {
    return this.leagueService.unpublishLeagueSeasonSchedule(leagueId, seasonId, input);
  }

  @Post(':leagueId/seasons/:seasonId/schedule/races')
  @ApiOperation({ summary: 'Create a schedule race for a league season (admin/owner only; actor derived from session)' })
  @ApiBody({ type: CreateLeagueScheduleRaceInputDTO })
  @ApiResponse({ status: 201, description: 'Race created', type: CreateLeagueScheduleRaceOutputDTO })
  async createLeagueSeasonScheduleRace(
    @Param('leagueId') leagueId: string,
    @Param('seasonId') seasonId: string,
    @Body(
      new ValidationPipe({
        whitelist: true,
        forbidNonWhitelisted: true,
        transform: true,
        expectedType: CreateLeagueScheduleRaceInputDTO,
      }),
    )
    input: CreateLeagueScheduleRaceInputDTO,
  ): Promise<CreateLeagueScheduleRaceOutputDTO> {
    return this.leagueService.createLeagueSeasonScheduleRace(leagueId, seasonId, input);
  }

  @Patch(':leagueId/seasons/:seasonId/schedule/races/:raceId')
  @ApiOperation({ summary: 'Update a schedule race for a league season (admin/owner only; actor derived from session)' })
  @ApiBody({ type: UpdateLeagueScheduleRaceInputDTO })
  @ApiResponse({ status: 200, description: 'Race updated', type: LeagueScheduleRaceMutationSuccessDTO })
  async updateLeagueSeasonScheduleRace(
    @Param('leagueId') leagueId: string,
    @Param('seasonId') seasonId: string,
    @Param('raceId') raceId: string,
    @Body(
      new ValidationPipe({
        whitelist: true,
        forbidNonWhitelisted: true,
        transform: true,
        expectedType: UpdateLeagueScheduleRaceInputDTO,
      }),
    )
    input: UpdateLeagueScheduleRaceInputDTO,
  ): Promise<LeagueScheduleRaceMutationSuccessDTO> {
    return this.leagueService.updateLeagueSeasonScheduleRace(leagueId, seasonId, raceId, input);
  }

  @Delete(':leagueId/seasons/:seasonId/schedule/races/:raceId')
  @ApiOperation({ summary: 'Delete a schedule race for a league season (admin/owner only; actor derived from session)' })
  @ApiResponse({ status: 200, description: 'Race deleted', type: LeagueScheduleRaceMutationSuccessDTO })
  async deleteLeagueSeasonScheduleRace(
    @Param('leagueId') leagueId: string,
    @Param('seasonId') seasonId: string,
    @Param('raceId') raceId: string,
  ): Promise<LeagueScheduleRaceMutationSuccessDTO> {
    return this.leagueService.deleteLeagueSeasonScheduleRace(leagueId, seasonId, raceId);
  }

  @Public()
  @Get(':leagueId/stats')
  @ApiOperation({ summary: 'Get league stats' })
  @ApiResponse({ status: 200, description: 'League stats', type: LeagueStatsDTO })
  async getLeagueStats(@Param('leagueId') leagueId: string): Promise<LeagueStatsDTO> {
    return this.leagueService.getLeagueStats(leagueId);
  }

  @Get(':leagueId/admin/roster/members')
  @ApiOperation({ summary: 'Get league roster members (admin/owner only; actor derived from session)' })
  @ApiResponse({ status: 200, description: 'List of league roster members', type: [LeagueRosterMemberDTO] })
  async getLeagueRosterMembers(@Param('leagueId') leagueId: string): Promise<LeagueRosterMemberDTO[]> {
    return this.leagueService.getLeagueRosterMembers(leagueId);
  }

  @Patch(':leagueId/admin/roster/members/:targetDriverId/role')
  @HttpCode(200)
  @ApiOperation({ summary: "Change a roster member's role (admin/owner only; actor derived from session)" })
  @ApiBody({ type: UpdateLeagueMemberRoleInputDTO })
  @ApiResponse({ status: 200, description: 'Member role updated successfully', type: UpdateLeagueMemberRoleOutputDTO })
  @ApiResponse({ status: 400, description: 'Cannot update role' })
  @ApiResponse({ status: 403, description: 'Forbidden' })
  @ApiResponse({ status: 404, description: 'Member not found' })
  async updateLeagueRosterMemberRole(
    @Param('leagueId') leagueId: string,
    @Param('targetDriverId') targetDriverId: string,
    @Body(
      new ValidationPipe({
        whitelist: true,
        forbidNonWhitelisted: true,
        transform: true,
        expectedType: UpdateLeagueMemberRoleInputDTO,
      }),
    )
    input: UpdateLeagueMemberRoleInputDTO,
  ): Promise<UpdateLeagueMemberRoleOutputDTO> {
    return this.leagueService.updateLeagueMemberRole(leagueId, targetDriverId, input);
  }

  @Patch(':leagueId/admin/roster/members/:targetDriverId/remove')
  @HttpCode(200)
  @ApiOperation({ summary: 'Remove a roster member (admin/owner only; actor derived from session)' })
  @ApiResponse({ status: 200, description: 'Member removed successfully', type: RemoveLeagueMemberOutputDTO })
  @ApiResponse({ status: 400, description: 'Cannot remove member' })
  @ApiResponse({ status: 403, description: 'Forbidden' })
  @ApiResponse({ status: 404, description: 'Member not found' })
  async removeLeagueRosterMember(
    @Param('leagueId') leagueId: string,
    @Param('targetDriverId') targetDriverId: string,
  ): Promise<RemoveLeagueMemberOutputDTO> {
    return this.leagueService.removeLeagueMember({ leagueId, targetDriverId });
  }

  @Get(':leagueId/admin/roster/join-requests')
  @ApiOperation({ summary: 'Get league roster join requests (admin/owner only; actor derived from session)' })
  @ApiResponse({ status: 200, description: 'List of league join requests', type: [LeagueRosterJoinRequestDTO] })
  async getLeagueRosterJoinRequests(@Param('leagueId') leagueId: string): Promise<LeagueRosterJoinRequestDTO[]> {
    return this.leagueService.getLeagueRosterJoinRequests(leagueId);
  }

  @Post(':leagueId/admin/roster/join-requests/:joinRequestId/approve')
  @HttpCode(200)
  @ApiOperation({ summary: 'Approve a league roster join request (admin/owner only; actor derived from session)' })
  @ApiResponse({ status: 200, description: 'Join request approved', type: ApproveJoinRequestOutputDTO })
  @ApiResponse({ status: 404, description: 'Join request not found' })
  async approveLeagueRosterJoinRequest(
    @Param('leagueId') leagueId: string,
    @Param('joinRequestId') joinRequestId: string,
  ): Promise<ApproveJoinRequestOutputDTO> {
    return this.leagueService.approveLeagueRosterJoinRequest(leagueId, joinRequestId);
  }

  @Post(':leagueId/admin/roster/join-requests/:joinRequestId/reject')
  @HttpCode(200)
  @ApiOperation({ summary: 'Reject a league roster join request (admin/owner only; actor derived from session)' })
  @ApiResponse({ status: 200, description: 'Join request rejected', type: RejectJoinRequestOutputDTO })
  @ApiResponse({ status: 404, description: 'Join request not found' })
  async rejectLeagueRosterJoinRequest(
    @Param('leagueId') leagueId: string,
    @Param('joinRequestId') joinRequestId: string,
  ): Promise<RejectJoinRequestOutputDTO> {
    return this.leagueService.rejectLeagueRosterJoinRequest(leagueId, joinRequestId);
  }

  @Get(':leagueId/admin')
  @ApiOperation({ summary: 'Get league admin data' })
  @ApiResponse({ status: 200, description: 'League admin data', type: LeagueAdminDTO })
  async getLeagueAdmin(@Param('leagueId') leagueId: string): Promise<LeagueAdminDTO> {
    return this.leagueService.getLeagueAdmin(leagueId);
  }

  @Post()
  @ApiOperation({ summary: 'Create a new league' })
  @ApiBody({ type: CreateLeagueInputDTO })
  @ApiResponse({ status: 201, description: 'League created successfully', type: CreateLeagueOutputDTO })
  async createLeague(@Body() input: CreateLeagueInputDTO): Promise<CreateLeagueOutputDTO> {
    return this.leagueService.createLeague(input);
  }

  @Public()
  @Get('scoring-presets')
  @ApiOperation({ summary: 'Get league scoring presets' })
  @ApiResponse({ status: 200, description: 'List of scoring presets', type: LeagueScoringPresetsDTO })
  async getLeagueScoringPresets(): Promise<LeagueScoringPresetsDTO> {
    return this.leagueService.listLeagueScoringPresets();
  }

  @Public()
  @Get(':leagueId/scoring-config')
  @ApiOperation({ summary: 'Get league scoring config' })
  @ApiResponse({ status: 200, description: 'League scoring config' })
  async getLeagueScoringConfig(@Param('leagueId') leagueId: string) {
    return this.leagueService.getLeagueScoringConfig(leagueId);
  }

  @Post(':leagueId/join')
  @ApiOperation({ summary: 'Join a league (actor derived from session)' })
  @ApiResponse({ status: 200, description: 'Joined league successfully' })
  async joinLeague(@Param('leagueId') leagueId: string) {
    return this.leagueService.joinLeague(leagueId);
  }

  @Post(':leagueId/transfer-ownership')
  @ApiOperation({ summary: 'Transfer league ownership' })
  @ApiBody({ type: TransferLeagueOwnershipInputDTO })
  @ApiResponse({ status: 200, description: 'Ownership transferred successfully' })
  async transferLeagueOwnership(
    @Param('leagueId') leagueId: string,
    @Body(
      new ValidationPipe({
        whitelist: true,
        forbidNonWhitelisted: true,
        transform: true,
        expectedType: TransferLeagueOwnershipInputDTO,
      }),
    )
    input: TransferLeagueOwnershipInputDTO,
  ) {
    return this.leagueService.transferLeagueOwnership(leagueId, input);
  }

  @Public()
  @Get('seasons/:seasonId/sponsorships')
  @ApiOperation({ summary: 'Get season sponsorships' })
  @ApiResponse({ status: 200, description: 'Season sponsorships', type: GetSeasonSponsorshipsOutputDTO })
  async getSeasonSponsorships(@Param('seasonId') seasonId: string): Promise<GetSeasonSponsorshipsOutputDTO> {
    return this.leagueService.getSeasonSponsorships(seasonId);
  }

  @Public()
  @Get(':leagueId/races')
  @ApiOperation({ summary: 'Get league races' })
  @ApiResponse({ status: 200, description: 'League races', type: GetLeagueRacesOutputDTO })
  async getRaces(@Param('leagueId') leagueId: string): Promise<GetLeagueRacesOutputDTO> {
    return this.leagueService.getRaces(leagueId);
  }

  @Get(':leagueId/wallet')
  @ApiOperation({ summary: 'Get league wallet information' })
  @ApiResponse({ status: 200, description: 'League wallet data', type: GetLeagueWalletOutputDTO })
  async getLeagueWallet(@Param('leagueId') leagueId: string): Promise<GetLeagueWalletOutputDTO> {
    return this.leagueService.getLeagueWallet(leagueId);
  }

  @Post(':leagueId/wallet/withdraw')
  @ApiOperation({ summary: 'Withdraw from league wallet' })
  @ApiBody({ type: WithdrawFromLeagueWalletInputDTO })
  @ApiResponse({ status: 200, description: 'Withdrawal processed', type: WithdrawFromLeagueWalletOutputDTO })
  async withdrawFromLeagueWallet(
    @Param('leagueId') leagueId: string,
    @Body() input: WithdrawFromLeagueWalletInputDTO,
  ): Promise<WithdrawFromLeagueWalletOutputDTO> {
    return this.leagueService.withdrawFromLeagueWallet(leagueId, input);
  }
}
