import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  ParseUUIDPipe,
  Patch,
  Post,
  Query,
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { CurrentUser } from '@edr/api-common';
import type { TCurrentUser } from '@tria-plc/api-common/modules/auth/types/current-user.type';
import { FleetManage, StaffReference } from '../../common/booking-guards';
import { FREIGHT_PERMS } from '../../seed/freight-permissions.registry';
import { CreateWagonDto } from './dto/create-wagon.dto';
import { ListWagonsQueryDto } from './dto/list-wagons-query.dto';
import { UpdateWagonDto } from './dto/update-wagon.dto';
import { AssignWagonToTrainDto } from './dto/assign-wagon-to-train.dto';
import { BulkTransferWagonsDto } from './dto/bulk-transfer-wagons.dto';
import { BulkSetWagonStatusDto } from './dto/bulk-set-wagon-status.dto';
import { WagonsService } from './wagons.service';

@ApiTags('wagons')
// No class-level guard: reads (list, by-id, movements) are login-only reference
// data — any staff can fetch wagon data for a cross-flow view without the
// fleet:view that drives the Fleet sidebar. Every mutation has its @FleetManage().
@Controller('wagons')
export class WagonsController {
  constructor(private readonly wagonsService: WagonsService) {}

  @Post()
  @FleetManage(FREIGHT_PERMS.wagons.create)
  @ApiOperation({ summary: 'Create a new wagon' })
  create(@Body() dto: CreateWagonDto) {
    return this.wagonsService.create(dto);
  }

  @Get()
  @StaffReference()
  @ApiOperation({ summary: 'List all wagons' })
  findAll(@Query() query: ListWagonsQueryDto) {
    return this.wagonsService.findAll(query);
  }

  @Get(':id')
  @StaffReference()
  @ApiOperation({ summary: 'Get a wagon by ID' })
  findOne(@Param('id', ParseUUIDPipe) id: string) {
    return this.wagonsService.findById(id);
  }

  @Get(':id/movements')
  @StaffReference()
  @ApiOperation({
    summary: "Wagon movement ledger (loaded legs, empty repositions, manual moves), newest first",
  })
  listMovements(@Param('id', ParseUUIDPipe) id: string) {
    return this.wagonsService.listMovements(id);
  }

  @Patch(':id')
  @FleetManage(FREIGHT_PERMS.wagons.update)
  @ApiOperation({ summary: 'Update a wagon' })
  update(@Param('id', ParseUUIDPipe) id: string, @Body() dto: UpdateWagonDto) {
    return this.wagonsService.update(id, dto);
  }

  @Delete(':id')
  @FleetManage(FREIGHT_PERMS.wagons.delete)
  @ApiOperation({ summary: 'Delete a wagon' })
  remove(@Param('id', ParseUUIDPipe) id: string) {
    return this.wagonsService.remove(id);
  }

  @Post(':id/assign-train')
  @FleetManage(FREIGHT_PERMS.trains.assignWagons)
  @ApiOperation({ summary: 'Assign wagon to a train' })
  assignToTrain(@Param('id', ParseUUIDPipe) id: string, @Body() dto: AssignWagonToTrainDto) {
    return this.wagonsService.assignToTrain(id, dto);
  }

  @Post(':id/unassign-train')
  @FleetManage(FREIGHT_PERMS.trains.assignWagons)
  @ApiOperation({ summary: 'Unassign wagon from train' })
  unassignFromTrain(@Param('id', ParseUUIDPipe) id: string) {
    return this.wagonsService.unassignFromTrain(id);
  }

  @Post('bulk-transfer')
  @FleetManage(FREIGHT_PERMS.wagons.update)
  @ApiOperation({ summary: 'Transfer multiple wagons to a destination yard' })
  bulkTransfer(@Body() dto: BulkTransferWagonsDto, @CurrentUser() user: TCurrentUser) {
    return this.wagonsService.bulkTransfer(dto, user?.id);
  }

  @Post('bulk-status')
  @FleetManage(FREIGHT_PERMS.wagons.update)
  @ApiOperation({ summary: 'Set the status of multiple wagons' })
  bulkSetStatus(@Body() dto: BulkSetWagonStatusDto) {
    return this.wagonsService.bulkSetStatus(dto);
  }
}
