import {
  Controller,
  Get,
  Put,
  Post,
  Delete,
  Param,
  Body,
  Query,
  UseGuards,
  ParseUUIDPipe,
  HttpCode,
  HttpStatus,
} from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation, ApiQuery } 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, JwtPayload } from '../../../common/decorators/current-user.decorator';
import { RequireModule } from '../../../common/decorators/require-module.decorator';
import { ModuleGuard } from '../../../common/guards/module.guard';
import { StaffScheduleService } from '../services/staff-schedule.service';
import { SetStaffScheduleDto, CreateStaffExceptionDto } from '../dto/staff-schedule.dto';

@ApiTags('Booking / Staff Schedule')
@ApiBearerAuth()
@Controller('booking/staff-schedule')
@UseGuards(JwtAuthGuard, ModuleGuard)
@RequireModule('booking')
export class BookingScheduleController {
  constructor(private readonly scheduleService: StaffScheduleService) {}

  @Get()
  @ApiOperation({ summary: 'Get all staff schedules for the club' })
  async getAllSchedules(@CurrentUser() user: JwtPayload) {
    return this.scheduleService.getAllStaffSchedules(user.clubId);
  }

  @Get(':staffId')
  @ApiOperation({ summary: 'Get weekly schedule for a staff member' })
  async getSchedule(
    @CurrentUser() user: JwtPayload,
    @Param('staffId', ParseUUIDPipe) staffId: string,
  ) {
    return this.scheduleService.getSchedule(user.clubId, staffId);
  }

  @Put(':staffId')
  @UseGuards(RolesGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.CLUB_ADMIN, UserRole.MANAGER)
  @ApiOperation({ summary: 'Set weekly schedule (replaces existing)' })
  async setSchedule(
    @CurrentUser() user: JwtPayload,
    @Param('staffId', ParseUUIDPipe) staffId: string,
    @Body() dto: SetStaffScheduleDto,
  ) {
    return this.scheduleService.setSchedule(user.clubId, staffId, dto);
  }

  @Get(':staffId/exceptions')
  @ApiOperation({ summary: 'Get schedule exceptions (day off, extra workday)' })
  @ApiQuery({ name: 'from', required: false, type: String, example: '2026-03-01' })
  @ApiQuery({ name: 'to', required: false, type: String, example: '2026-03-31' })
  async getExceptions(
    @CurrentUser() user: JwtPayload,
    @Param('staffId', ParseUUIDPipe) staffId: string,
    @Query('from') from?: string,
    @Query('to') to?: string,
  ) {
    return this.scheduleService.getExceptions(
      user.clubId,
      staffId,
      from ? new Date(from) : undefined,
      to ? new Date(to) : undefined,
    );
  }

  @Post(':staffId/exceptions')
  @UseGuards(RolesGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.CLUB_ADMIN, UserRole.MANAGER)
  @ApiOperation({ summary: 'Create/update a schedule exception' })
  async createException(
    @CurrentUser() user: JwtPayload,
    @Param('staffId', ParseUUIDPipe) staffId: string,
    @Body() dto: CreateStaffExceptionDto,
  ) {
    return this.scheduleService.createException(user.clubId, staffId, dto);
  }

  @Delete('exceptions/:id')
  @UseGuards(RolesGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.CLUB_ADMIN, UserRole.MANAGER)
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: 'Delete a schedule exception' })
  async deleteException(@Param('id', ParseUUIDPipe) id: string) {
    await this.scheduleService.deleteException(id);
  }
}
