import {
  Controller, Get, Post, Patch, Delete,
  Body, Param, Query, UseGuards, ParseUUIDPipe,
} from '@nestjs/common';
import { BookingService } from './booking.service';
import { UpdateBookingDto, AssignTransportItemDto, BulkAssignTransportItemDto } from './dto';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { PermissionGuard } from '../../auth/guards/permission.guard';
import { Permissions } from '../../auth/decorators/permissions.decorator';
import { AccessLevel, ModuleName } from '../../entities/role-permission.entity';
import { paginatedResponse, successResponse } from '../../common/responses/api-response';
import { PaginationDto } from '../../common/dto/pagination.dto';
import { BookingStatus } from '../../entities/booking.entity';

@Controller('bookings')
@UseGuards(JwtAuthGuard, PermissionGuard)
export class BookingController {
  constructor(private readonly service: BookingService) {}

  @Get()
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.VIEW })
  async findAll(
    @Query() query: PaginationDto,
    @Query('status') status?: string,
    @Query('destination_id') destinationId?: string,
    @Query('date_from') dateFrom?: string,
    @Query('date_to') dateTo?: string,
  ) {
    const { items, meta } = await this.service.findAll(query, { status, destinationId, dateFrom, dateTo });
    return paginatedResponse(items, meta, 'Bookings fetched successfully');
  }

  @Get('transport-dates')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.VIEW })
  async getTransportDates(
    @Query('destination_id') destinationId: string,
  ) {
    const data = await this.service.getTransportDates(destinationId);
    return successResponse(data, 'Transport dates fetched');
  }

  @Get('movement-chart')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.VIEW })
  async getMovementChart(
    @Query('destination_id') destinationId: string,
    @Query('date') date: string,
  ) {
    const data = await this.service.getMovementChart(destinationId, date);
    return successResponse(data, 'Movement chart fetched successfully');
  }

  @Get('driver-assignments')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.VIEW })
  async getDriverAssignments(
    @Query('destination_id') destinationId: string,
    @Query('date') date: string,
    @Query('transport_service_id') transportServiceId?: string,
  ) {
    const data = await this.service.getDriverAssignments(destinationId, date, transportServiceId);
    return successResponse(data, 'Driver assignments fetched successfully');
  }

  @Patch('transport-items/bulk-assign')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.EDIT })
  async bulkAssign(@Body() dto: BulkAssignTransportItemDto) {
    const result = await this.service.bulkAssignTransportItems(dto);
    return successResponse(result, result.message);
  }

  @Patch('transport-items/:id/assign')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.EDIT })
  async assignTransportItem(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: AssignTransportItemDto,
  ) {
    const result = await this.service.assignTransportItem(id, dto);
    return successResponse(result, result.message);
  }

  @Get(':id')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.VIEW })
  async findById(@Param('id', ParseUUIDPipe) id: string) {
    const data = await this.service.findById(id);
    return successResponse(data, 'Booking fetched successfully');
  }

  @Post('from-query/:queryId')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.CREATE })
  async createFromQuery(@Param('queryId', ParseUUIDPipe) queryId: string) {
    const result = await this.service.createFromQuery(queryId);
    return successResponse(result, result.message);
  }

  @Patch(':id')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.EDIT })
  async update(@Param('id', ParseUUIDPipe) id: string, @Body() dto: UpdateBookingDto) {
    const result = await this.service.update(id, dto);
    return successResponse(result, result.message);
  }

  @Patch(':id/status')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.EDIT })
  async changeStatus(@Param('id', ParseUUIDPipe) id: string, @Body('status') status: BookingStatus) {
    const result = await this.service.changeStatus(id, status);
    return successResponse(result, result.message);
  }

  @Delete(':id')
  @Permissions({ module: ModuleName.BOOKING, accessLevel: AccessLevel.DELETE })
  async remove(@Param('id', ParseUUIDPipe) id: string) {
    const result = await this.service.remove(id);
    return successResponse(result, result.message);
  }
}
