import {
  Controller,
  Get,
  Post,
  Patch,
  Delete,
  Put,
  Param,
  Body,
  UseGuards,
  ParseUUIDPipe,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../auth/guards/roles.guard';
import { Roles, UserRole } from '../../common/decorators/roles.decorator';
import { CurrentUser, type JwtPayload } from '../../common/decorators/current-user.decorator';
import { RolesService } from './roles.service';

@ApiTags('Roles')
@ApiBearerAuth()
@Controller('roles')
@UseGuards(JwtAuthGuard)
export class RolesController {
  constructor(private readonly rolesService: RolesService) {}

  @Get()
  @ApiOperation({ summary: 'List all roles (built-in + custom)' })
  async findAll(@CurrentUser() user: JwtPayload) {
    const clubId = user.role === (UserRole.SUPER_ADMIN as string) ? null : user.clubId;
    return this.rolesService.findAll(clubId);
  }

  @Post()
  @UseGuards(RolesGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.CLUB_ADMIN)
  @ApiOperation({ summary: 'Create a custom role' })
  async create(@CurrentUser() user: JwtPayload, @Body() body: { name: string; slug: string }) {
    const clubId = user.clubId;
    return this.rolesService.create(clubId, body);
  }

  @Patch(':id')
  @UseGuards(RolesGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.CLUB_ADMIN)
  @ApiOperation({ summary: 'Rename a role' })
  async rename(@Param('id', ParseUUIDPipe) id: string, @Body() body: { name: string }) {
    return this.rolesService.rename(id, body.name);
  }

  @Delete(':id')
  @UseGuards(RolesGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.CLUB_ADMIN)
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Delete a custom role' })
  async delete(@Param('id', ParseUUIDPipe) id: string) {
    await this.rolesService.delete(id);
  }

  @Put('users/:userId/roles')
  @UseGuards(RolesGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.CLUB_ADMIN)
  @ApiOperation({ summary: 'Assign roles to a user' })
  async assignRoles(
    @Param('userId', ParseUUIDPipe) userId: string,
    @Body() body: { roleIds: string[] },
  ) {
    return this.rolesService.assignRoles(userId, body.roleIds);
  }

  @Get('users/:userId/roles')
  @ApiOperation({ summary: 'Get roles for a user' })
  async getUserRoles(@Param('userId', ParseUUIDPipe) userId: string) {
    return this.rolesService.getUserRoles(userId);
  }
}
