import { Body, Controller, Get, Param, ParseUUIDPipe, Post, Query } from '@nestjs/common';
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';

import { BookingStaff } from '../../common/booking-guards';
import { FREIGHT_PERMS } from '../../seed/freight-permissions.registry';
import {
  AssignCustomsRiskDto,
  CreateDjiboutiIncidentDto,
  CreateEmptyContainerReturnDto,
  ImportOperationActionDto,
  RecordDeclarationDto,
  UpdateEmptyContainerReturnStatusDto,
  UploadImportCustomsDocumentDto,
} from './dto/import-operations.dto';
import { ImportOperationsService } from './import-operations.service';

@ApiTags('import-operations')
@ApiBearerAuth()
@Controller('import-operations')
// Post-booking customs / import-operations actions are GL/Ops work, mirroring the
// contracts controller's GL operational endpoints (risk, duty, milestones).
@BookingStaff(FREIGHT_PERMS.bookings.operations)
export class ImportOperationsController {
  constructor(private readonly service: ImportOperationsService) {}

  @Get('djibouti-incidents')
  @ApiOperation({ summary: 'Batch 8: list Djibouti import incidents' })
  listIncidents(@Query('bookingId') bookingId?: string) {
    return this.service.listIncidents(bookingId);
  }

  @Post('djibouti-incidents')
  @ApiOperation({ summary: 'Batch 8: report a Djibouti import incident / exception' })
  createIncident(@Body() dto: CreateDjiboutiIncidentDto) {
    return this.service.createIncident(dto);
  }

  @Get('customs/:bookingId')
  @ApiOperation({ summary: 'Batch 12: import customs finalization state' })
  getCustoms(@Param('bookingId', ParseUUIDPipe) bookingId: string) {
    return this.service.getCustoms(bookingId);
  }

  @Post('customs/:bookingId/documents')
  @ApiOperation({ summary: 'Batch 12: upload IM4/IM5/T1/permit/payment-slip documents' })
  uploadCustomsDocument(
    @Param('bookingId', ParseUUIDPipe) bookingId: string,
    @Body() dto: UploadImportCustomsDocumentDto,
  ) {
    return this.service.uploadCustomsDocument(bookingId, dto);
  }

  @Post('customs/:bookingId/declaration')
  @ApiOperation({ summary: 'Batch 12: record declaration serial number' })
  recordDeclaration(
    @Param('bookingId', ParseUUIDPipe) bookingId: string,
    @Body() dto: RecordDeclarationDto,
  ) {
    return this.service.recordDeclaration(bookingId, dto);
  }

  @Post('customs/:bookingId/notify-duties-taxes')
  @ApiOperation({ summary: 'Batch 12: notify duties and taxes' })
  notifyDutiesTaxes(
    @Param('bookingId', ParseUUIDPipe) bookingId: string,
    @Body() dto: ImportOperationActionDto,
  ) {
    return this.service.notifyDutiesTaxes(bookingId, dto);
  }

  @Post('customs/:bookingId/duties-taxes-paid')
  @ApiOperation({ summary: 'Batch 12: mark duties and taxes paid' })
  markDutiesTaxesPaid(
    @Param('bookingId', ParseUUIDPipe) bookingId: string,
    @Body() dto: ImportOperationActionDto,
  ) {
    return this.service.markDutiesTaxesPaid(bookingId, dto);
  }

  @Post('customs/:bookingId/risk')
  @ApiOperation({ summary: 'Batch 12: assign customs risk' })
  assignRisk(@Param('bookingId', ParseUUIDPipe) bookingId: string, @Body() dto: AssignCustomsRiskDto) {
    return this.service.assignRisk(bookingId, dto);
  }

  @Post('customs/:bookingId/release-permitted')
  @ApiOperation({ summary: 'Batch 12: mark import release permitted' })
  markReleasePermitted(
    @Param('bookingId', ParseUUIDPipe) bookingId: string,
    @Body() dto: ImportOperationActionDto,
  ) {
    return this.service.markReleasePermitted(bookingId, dto);
  }

  @Get('empty-container-returns')
  @ApiOperation({ summary: 'Batch 16: list empty container returns' })
  listEmptyReturns() {
    return this.service.listEmptyReturns();
  }

  @Post('empty-container-returns')
  @ApiOperation({ summary: 'Batch 16: create an empty container return record' })
  createEmptyReturn(@Body() dto: CreateEmptyContainerReturnDto) {
    return this.service.createEmptyReturn(dto);
  }

  @Post('empty-container-returns/:id/status')
  @ApiOperation({ summary: 'Batch 16: advance empty container return workflow' })
  updateEmptyReturnStatus(
    @Param('id', ParseUUIDPipe) id: string,
    @Body() dto: UpdateEmptyContainerReturnStatusDto,
  ) {
    return this.service.updateEmptyReturnStatus(id, dto);
  }
}
