import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Query,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import {
  IsArray,
  IsDateString,
  IsEnum,
  IsNumber,
  IsOptional,
  IsString,
  IsUUID,
} from 'class-validator';
import { SpaceType, PricingType } from '@prisma/client';
import { BookingsService } from './bookings.service';
import { Roles } from '../../common/decorators/roles.decorator';
import { CurrentUser, AuthenticatedUser } from '../../common/decorators/current-user.decorator';

class CreateSpaceDto {
  @IsUUID() complexId!: string;
  @IsString() name!: string;
  @IsOptional() @IsEnum(SpaceType) type?: SpaceType;
  @IsOptional() @IsString() description?: string;
  @IsOptional() @IsNumber() capacity?: number;
  @IsOptional() @IsNumber() hourlyFee?: number;
  @IsOptional() @IsNumber() flatFee?: number;
  @IsOptional() @IsEnum(PricingType) priceType?: PricingType;
  @IsOptional() @IsString() imageUrl?: string;
  @IsOptional() @IsString() openTime?: string;
  @IsOptional() @IsString() closeTime?: string;
  @IsOptional() @IsArray() @IsString({ each: true }) amenities?: string[];
  @IsOptional() @IsString() rules?: string;
  @IsOptional() isBookable?: boolean;
}

class RequestBookingDto {
  @IsUUID() spaceId!: string;
  @IsDateString() startAt!: string;
  @IsDateString() endAt!: string;
  @IsOptional() @IsString() notes?: string;
}

@ApiTags('bookings')
@ApiBearerAuth()
@Controller()
export class BookingsController {
  constructor(private readonly service: BookingsService) {}

  @Post('common-spaces')
  @Roles('SUPERADMIN', 'SYNDIC')
  createSpace(@CurrentUser() user: AuthenticatedUser, @Body() dto: CreateSpaceDto) {
    return this.service.createSpace(user, dto);
  }

  @Get('common-spaces')
  listSpaces(@CurrentUser() user: AuthenticatedUser, @Query('complexId') complexId?: string) {
    return this.service.listSpaces(user, complexId);
  }

  @Post('bookings')
  request(@CurrentUser() user: AuthenticatedUser, @Body() dto: RequestBookingDto) {
    return this.service.request(user, {
      ...dto,
      startAt: new Date(dto.startAt),
      endAt: new Date(dto.endAt),
    });
  }

  @Get('bookings')
  list(
    @CurrentUser() user: AuthenticatedUser,
    @Query('spaceId') spaceId?: string,
    @Query('mine') mine?: string,
  ) {
    return this.service.list(user, { spaceId, mine: mine === 'true' });
  }

  @Patch('bookings/:id/confirm')
  @Roles('SUPERADMIN', 'SYNDIC')
  confirm(@CurrentUser() user: AuthenticatedUser, @Param('id') id: string) {
    return this.service.confirm(user, id);
  }

  @Delete('bookings/:id')
  cancel(@CurrentUser() user: AuthenticatedUser, @Param('id') id: string) {
    return this.service.cancel(user, id);
  }
}
