import {
  Controller,
  Get,
  Post,
  Patch,
  Delete,
  Param,
  Body,
  Query,
  UseGuards,
  ParseUUIDPipe,
  HttpCode,
  HttpStatus,
  ForbiddenException,
} 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 { BookingRecordsService } from '../services/records.service';
import { BookingPermissions } from '../core/booking-permissions';
import {
  CreateBookingRecordDto,
  UpdateBookingRecordDto,
  UpdateRecordStatusDto,
  FindRecordsQueryDto,
} from '../dto/create-record.dto';

@ApiTags('Booking / Records')
@ApiBearerAuth()
@Controller('booking/records')
@UseGuards(JwtAuthGuard, ModuleGuard)
@RequireModule('booking')
export class BookingRecordsController {
  constructor(
    private readonly recordsService: BookingRecordsService,
    private readonly permissions: BookingPermissions,
  ) {}

  @Get()
  @ApiOperation({ summary: 'List booking records (paginated)' })
  async findAll(@CurrentUser() user: JwtPayload, @Query() query: FindRecordsQueryDto) {
    const roleFilter = this.permissions.filterRecordsByRole(user.sub, user.role);
    return this.recordsService.findAll(user.clubId, query, roleFilter);
  }

  @Get('my-schedule')
  @ApiOperation({ summary: 'Get current user schedule for today' })
  @ApiQuery({ name: 'date', required: false, type: String, example: '2026-03-15' })
  async getMySchedule(@CurrentUser() user: JwtPayload, @Query('date') date?: string) {
    const targetDate = date ? new Date(date) : new Date();
    return this.recordsService.getTrainerSchedule(user.clubId, user.sub, targetDate);
  }

  @Get(':id')
  @ApiOperation({ summary: 'Get record by ID' })
  async findById(@Param('id', ParseUUIDPipe) id: string) {
    return this.recordsService.findById(id);
  }

  @Post()
  @UseGuards(RolesGuard)
  @Roles(UserRole.SUPER_ADMIN, UserRole.CLUB_ADMIN, UserRole.MANAGER, UserRole.RECEPTIONIST)
  @ApiOperation({ summary: 'Create a booking record' })
  async create(@CurrentUser() user: JwtPayload, @Body() dto: CreateBookingRecordDto) {
    return this.recordsService.create(user.clubId, dto, user.sub);
  }

  @Patch(':id')
  @ApiOperation({ summary: 'Update a booking record (reschedule, edit client data)' })
  async update(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateBookingRecordDto,
  ) {
    const record = await this.recordsService.findById(id);
    if (!this.permissions.canUpdateRecord(user.sub, user.role, record)) {
      throw new ForbiddenException();
    }
    return this.recordsService.update(id, dto);
  }

  @Patch(':id/status')
  @ApiOperation({ summary: 'Transition record status (confirm, complete, cancel, no-show)' })
  async updateStatus(
    @CurrentUser() user: JwtPayload,
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateRecordStatusDto,
  ) {
    const record = await this.recordsService.findById(id);
    if (!this.permissions.canMarkAttendance(user.sub, user.role, record)) {
      throw new ForbiddenException();
    }
    return this.recordsService.updateStatus(id, dto, user.sub);
  }

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