import {
  Body,
  Controller,
  Delete,
  Get,
  HttpCode,
  HttpStatus,
  Param,
  ParseIntPipe,
  Patch,
  Put,
  Query,
  Request,
  UseGuards,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { AuthGuard } from '@nestjs/passport';
import { Roles } from '../roles/roles.decorator';
import { RoleEnum } from '../roles/roles.enum';
import { RolesGuard } from '../roles/roles.guard';
import { AdminUsersService } from './admin-users.service';
import {
  AdminPlayerQueryDto,
  AdminUserProfileDto,
  AdminUserRoleDto,
  AdminUserStatusDto,
} from './dto/admin-user.dto';

type AdminRequest = { user: { id: number; role: { id: RoleEnum } } };

@ApiBearerAuth()
@ApiTags('Admin users')
@UseGuards(AuthGuard('jwt'), RolesGuard)
@Roles([RoleEnum.admin])
@Controller({ path: 'admin/users', version: '1' })
export class AdminUsersController {
  constructor(private readonly adminUsersService: AdminUsersService) {}

  @Patch(':id/profile')
  @HttpCode(HttpStatus.OK)
  updateProfile(
    @Request() request: AdminRequest,
    @Param('id', ParseIntPipe) id: number,
    @Body() dto: AdminUserProfileDto,
  ) {
    return this.adminUsersService.updateProfile(request.user.id, id, dto);
  }

  @Patch(':id/role')
  @HttpCode(HttpStatus.OK)
  updateRole(
    @Request() request: AdminRequest,
    @Param('id', ParseIntPipe) id: number,
    @Body() dto: AdminUserRoleDto,
  ) {
    return this.adminUsersService.updateRole(request.user.id, id, dto.role);
  }

  @Patch(':id/status')
  @HttpCode(HttpStatus.OK)
  updateStatus(
    @Request() request: AdminRequest,
    @Param('id', ParseIntPipe) id: number,
    @Body() dto: AdminUserStatusDto,
  ) {
    return this.adminUsersService.updateStatus(request.user.id, id, dto.status);
  }

  @Get('players')
  @HttpCode(HttpStatus.OK)
  findPlayers(@Query() query: AdminPlayerQueryDto) {
    return this.adminUsersService.findPlayers(query);
  }

  @Put(':userId/players/:playerId')
  @HttpCode(HttpStatus.OK)
  assignPlayer(
    @Request() request: AdminRequest,
    @Param('userId', ParseIntPipe) userId: number,
    @Param('playerId', ParseIntPipe) playerId: number,
  ) {
    return this.adminUsersService.assignPlayer(
      request.user.id,
      userId,
      playerId,
    );
  }

  @Delete(':userId/players/:playerId')
  @HttpCode(HttpStatus.OK)
  unlinkPlayer(
    @Request() request: AdminRequest,
    @Param('userId', ParseIntPipe) userId: number,
    @Param('playerId', ParseIntPipe) playerId: number,
  ) {
    return this.adminUsersService.unlinkPlayer(
      request.user.id,
      userId,
      playerId,
    );
  }
}
