import {
  BadRequestException,
  Body,
  Controller,
  Delete,
  Param,
  ParseIntPipe,
  Post,
} from '@nestjs/common';
import {
  allocateVolunteersSchema,
  checkInSchema,
  checkOutSchema,
  approveDistanceSchema,
  type CheckInInput,
  type CheckOutInput,
  type AuthUser,
} from '@vihar/shared';
import { AllocationsService } from './allocations.service';
import { ZodValidationPipe } from '../../common/pipes/zod-validation.pipe';
import { CurrentUser, RequiresCaptain } from '../../common/decorators/auth.decorators';

@Controller()
export class AllocationsController {
  constructor(private readonly allocations: AllocationsService) {}

  @Post('vihars/:viharId/allocations')
  @RequiresCaptain()
  allocate(
    @CurrentUser() user: AuthUser,
    @Param('viharId', ParseIntPipe) viharId: number,
    @Body(new ZodValidationPipe(allocateVolunteersSchema)) input: { userIds: number[] },
  ) {
    if (!user.cityId) throw new BadRequestException('No city scope');
    return this.allocations.allocate(user.cityId, viharId, user.userId, input.userIds);
  }

  @Delete('allocations/:allocationId')
  @RequiresCaptain()
  deallocate(
    @CurrentUser() user: AuthUser,
    @Param('allocationId', ParseIntPipe) allocationId: number,
  ) {
    if (!user.cityId) throw new BadRequestException('No city scope');
    return this.allocations.deallocate(user.cityId, allocationId, user.userId);
  }

  @Post('allocations/:allocationId/check-in')
  checkIn(
    @CurrentUser() user: AuthUser,
    @Param('allocationId', ParseIntPipe) allocationId: number,
    @Body(new ZodValidationPipe(checkInSchema)) input: CheckInInput,
  ) {
    if (!user.cityId) throw new BadRequestException('No city scope');
    return this.allocations.checkIn(user.cityId, allocationId, user.userId, input);
  }

  @Post('allocations/:allocationId/check-out')
  checkOut(
    @CurrentUser() user: AuthUser,
    @Param('allocationId', ParseIntPipe) allocationId: number,
    @Body(new ZodValidationPipe(checkOutSchema)) input: CheckOutInput,
  ) {
    if (!user.cityId) throw new BadRequestException('No city scope');
    return this.allocations.checkOut(user.cityId, allocationId, user.userId, input, false);
  }

  @Post('allocations/:allocationId/check-out-on-behalf')
  @RequiresCaptain()
  checkOutOnBehalf(
    @CurrentUser() user: AuthUser,
    @Param('allocationId', ParseIntPipe) allocationId: number,
    @Body(new ZodValidationPipe(checkOutSchema)) input: CheckOutInput,
  ) {
    if (!user.cityId) throw new BadRequestException('No city scope');
    return this.allocations.checkOut(user.cityId, allocationId, user.userId, input, true);
  }

  @Post('allocations/:allocationId/approve-distance')
  @RequiresCaptain()
  approveDistance(
    @CurrentUser() user: AuthUser,
    @Param('allocationId', ParseIntPipe) allocationId: number,
    @Body(new ZodValidationPipe(approveDistanceSchema)) input: { approvedKm: number; decision: 'approved' | 'rejected' },
  ) {
    if (!user.cityId) throw new BadRequestException('No city scope');
    return this.allocations.approveDistance(user.cityId, allocationId, user.userId, input);
  }
}
