import { Controller, Get, Post, Patch, Body, Param } from '@nestjs/common';
import { ApiTags, ApiResponse, ApiOperation, ApiBody } from '@nestjs/swagger';
import { TeamService } from './TeamService';
import { AllTeamsViewModel, DriverTeamViewModel, TeamDetailsViewModel, TeamMembersViewModel, TeamJoinRequestsViewModel, CreateTeamInput, CreateTeamOutput, UpdateTeamInput, UpdateTeamOutput, ApproveTeamJoinRequestInput, ApproveTeamJoinRequestOutput, RejectTeamJoinRequestInput, RejectTeamJoinRequestOutput } from './dto/TeamDto';

@ApiTags('teams')
@Controller('teams')
export class TeamController {
  constructor(private readonly teamService: TeamService) {}

  @Get('all')
  @ApiOperation({ summary: 'Get all teams' })
  @ApiResponse({ status: 200, description: 'List of all teams', type: AllTeamsViewModel })
  async getAllTeams(): Promise<AllTeamsViewModel> {
    return this.teamService.getAllTeams();
  }

  @Get(':teamId')
  @ApiOperation({ summary: 'Get team details' })
  @ApiResponse({ status: 200, description: 'Team details', type: TeamDetailsViewModel })
  @ApiResponse({ status: 404, description: 'Team not found' })
  async getTeamDetails(
    @Param('teamId') teamId: string,
  ): Promise<TeamDetailsViewModel | null> {
    return this.teamService.getTeamDetails(teamId);
  }

  @Get(':teamId/members')
  @ApiOperation({ summary: 'Get team members' })
  @ApiResponse({ status: 200, description: 'Team members', type: TeamMembersViewModel })
  async getTeamMembers(@Param('teamId') teamId: string): Promise<TeamMembersViewModel> {
    return this.teamService.getTeamMembers(teamId);
  }

  @Get(':teamId/join-requests')
  @ApiOperation({ summary: 'Get team join requests' })
  @ApiResponse({ status: 200, description: 'Team join requests', type: TeamJoinRequestsViewModel })
  async getTeamJoinRequests(@Param('teamId') teamId: string): Promise<TeamJoinRequestsViewModel> {
    return this.teamService.getTeamJoinRequests(teamId);
  }

  @Post(':teamId/join-requests/approve')
  @ApiOperation({ summary: 'Approve a team join request' })
  @ApiBody({ type: ApproveTeamJoinRequestInput })
  @ApiResponse({ status: 200, description: 'Join request approved', type: ApproveTeamJoinRequestOutput })
  @ApiResponse({ status: 404, description: 'Join request not found' })
  async approveJoinRequest(
    @Param('teamId') teamId: string,
    @Body() input: ApproveTeamJoinRequestInput,
  ): Promise<ApproveTeamJoinRequestOutput> {
    return this.teamService.approveTeamJoinRequest({ ...input, teamId });
  }

  @Post(':teamId/join-requests/reject')
  @ApiOperation({ summary: 'Reject a team join request' })
  @ApiBody({ type: RejectTeamJoinRequestInput })
  @ApiResponse({ status: 200, description: 'Join request rejected', type: RejectTeamJoinRequestOutput })
  @ApiResponse({ status: 404, description: 'Join request not found' })
  async rejectJoinRequest(
    @Param('teamId') teamId: string,
    @Body() input: RejectTeamJoinRequestInput,
  ): Promise<RejectTeamJoinRequestOutput> {
    return this.teamService.rejectTeamJoinRequest({ ...input, teamId });
  }

  @Post()
  @ApiOperation({ summary: 'Create a new team' })
  @ApiBody({ type: CreateTeamInput })
  @ApiResponse({ status: 201, description: 'Team created successfully', type: CreateTeamOutput })
  async createTeam(@Body() input: CreateTeamInput): Promise<CreateTeamOutput> {
    return this.teamService.createTeam(input);
  }

  @Patch(':teamId')
  @ApiOperation({ summary: 'Update team details' })
  @ApiBody({ type: UpdateTeamInput })
  @ApiResponse({ status: 200, description: 'Team updated successfully', type: UpdateTeamOutput })
  @ApiResponse({ status: 404, description: 'Team not found' })
  async updateTeam(
    @Param('teamId') teamId: string,
    @Body() input: UpdateTeamInput,
  ): Promise<UpdateTeamOutput> {
    return this.teamService.updateTeam({ ...input, teamId });
  }

  @Get('driver/:driverId')
  @ApiOperation({ summary: 'Get team for a driver' })
  @ApiResponse({ status: 200, description: 'Driver team membership', type: DriverTeamViewModel })
  @ApiResponse({ status: 404, description: 'Driver not in a team' })
  async getDriverTeam(@Param('driverId') driverId: string): Promise<DriverTeamViewModel | null> {
    return this.teamService.getDriverTeam({ teamId: '', driverId });
  }

  @Get('leaderboard')
  @ApiOperation({ summary: 'Get teams leaderboard' })
  @ApiResponse({ status: 200, description: 'Teams leaderboard' })
  async getTeamsLeaderboard(): Promise<any> {
    return this.teamService.getTeamsLeaderboard();
  }
}
