import { Controller, Get, Post, Patch, Body, Req, Param, Inject } from '@nestjs/common';
import { ApiTags, ApiResponse, ApiOperation } from '@nestjs/swagger';
import { Public } from '../auth/Public';

type RequestWithUser = Record<string, unknown> & {
  user?: {
    userId?: string;
  };
};
import { TeamService } from './TeamService';
import { GetAllTeamsOutputDTO } from './dtos/GetAllTeamsOutputDTO';
import { GetTeamDetailsOutputDTO } from './dtos/GetTeamDetailsOutputDTO';
import { GetTeamMembersOutputDTO } from './dtos/GetTeamMembersOutputDTO';
import { GetTeamJoinRequestsOutputDTO } from './dtos/GetTeamJoinRequestsOutputDTO';
import { CreateTeamInputDTO } from './dtos/CreateTeamInputDTO';
import { CreateTeamOutputDTO } from './dtos/CreateTeamOutputDTO';
import { UpdateTeamInput } from './dtos/TeamDto';
import { UpdateTeamOutputDTO } from './dtos/UpdateTeamOutputDTO';
import { GetDriverTeamOutputDTO } from './dtos/GetDriverTeamOutputDTO';
import { GetTeamMembershipOutputDTO } from './dtos/GetTeamMembershipOutputDTO';

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

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

  @Public()
  @Get(':teamId')
  @ApiOperation({ summary: 'Get team details' })
  @ApiResponse({ status: 200, description: 'Team details', type: GetTeamDetailsOutputDTO })
  @ApiResponse({ status: 404, description: 'Team not found' })
  async getDetails(@Param('teamId') teamId: string, @Req() req: RequestWithUser): Promise<GetTeamDetailsOutputDTO | null> {
    const userId = req.user?.userId;
    return await this.teamService.getDetails(teamId, userId);
  }

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

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

  @Post()
  @ApiOperation({ summary: 'Create a new team' })
  @ApiResponse({ status: 201, description: 'Team created', type: CreateTeamOutputDTO })
  async create(@Body() input: CreateTeamInputDTO, @Req() req: RequestWithUser): Promise<CreateTeamOutputDTO> {
    const userId = req.user?.userId;
    return await this.teamService.create(input, userId);
  }

  @Patch(':teamId')
  @ApiOperation({ summary: 'Update team' })
  @ApiResponse({ status: 200, description: 'Team updated', type: UpdateTeamOutputDTO })
  async update(@Param('teamId') teamId: string, @Body() input: UpdateTeamInput, @Req() req: RequestWithUser): Promise<UpdateTeamOutputDTO> {
    const userId = req.user?.userId;
    return await this.teamService.update(teamId, input, userId);
  }

  @Public()
  @Get('driver/:driverId')
  @ApiOperation({ summary: 'Get driver\'s team' })
  @ApiResponse({ status: 200, description: 'Driver\'s team', type: GetDriverTeamOutputDTO })
  @ApiResponse({ status: 404, description: 'Team not found' })
  async getDriverTeam(@Param('driverId') driverId: string): Promise<GetDriverTeamOutputDTO | null> {
    return await this.teamService.getDriverTeam(driverId);
  }

  @Public()
  @Get(':teamId/members/:driverId')
  @ApiOperation({ summary: 'Get team membership for a driver' })
  @ApiResponse({ status: 200, description: 'Team membership', type: GetTeamMembershipOutputDTO })
  @ApiResponse({ status: 404, description: 'Membership not found' })
  async getMembership(@Param('teamId') teamId: string, @Param('driverId') driverId: string): Promise<GetTeamMembershipOutputDTO | null> {
    return await this.teamService.getMembership(teamId, driverId);
  }
}