import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiBody, ApiResponse } from '@nestjs/swagger';
import { FleetService } from './fleet.service';
import { CreateTrainDto, CreateCoachDto, UpdateCoachDto, AssignCoachDto, CreateSeatBatchDto, ListCoachesDto } from './fleet.dto';
import { JwtGuard } from '../../common/jwt.guard';

@ApiTags('Fleet')
@Controller('fleet')
@UseGuards(JwtGuard)
@ApiBearerAuth('JWT-auth')
export class FleetController {
  constructor(private service: FleetService) {}

  @Get('trains')
  @ApiOperation({ summary: 'List all trains with their recent schedules' })
  @ApiResponse({ status: 200, description: 'Array of trains each with up to 5 most recent schedules' })
  getTrains() { return this.service.getTrains(); }

  @Post('trains')
  @ApiOperation({ summary: 'Create a train service' })
  @ApiBody({ type: CreateTrainDto })
  @ApiResponse({ status: 201, description: 'Train created' })
  createTrain(@Body() dto: CreateTrainDto) { return this.service.createTrain(dto); }

  @Get('coaches')
  @ApiOperation({ summary: 'List coaches filtered by status, mode, seat class, or schedule assignment' })
  @ApiQuery({ name: 'isActive', required: false, type: Boolean, description: 'true = active only, false = inactive only, omit = all' })
  @ApiQuery({ name: 'mode', required: false, description: 'Filter by mode: seat | bed | convertible' })
  @ApiQuery({ name: 'seatClassId', required: false, description: 'Filter by SeatClass UUID' })
  @ApiQuery({ name: 'scheduleId', required: false, description: 'Filter to coaches assigned to this TrainSchedule UUID' })
  @ApiResponse({ status: 200, description: 'Coaches with seat class info, assignment count, and seat status summary (total/available/held/booked/blocked)' })
  listCoaches(
    @Query('isActive') isActive?: string,
    @Query('mode') mode?: string,
    @Query('seatClassId') seatClassId?: string,
    @Query('scheduleId') scheduleId?: string,
  ) {
    const dto: ListCoachesDto = {
      isActive: isActive === 'true' ? true : isActive === 'false' ? false : undefined,
      mode,
      seatClassId,
      scheduleId,
    };
    return this.service.listCoaches(dto);
  }

  @Get('coaches/:id')
  @ApiOperation({ summary: 'Get a single coach with full seat layout and arrangement' })
  @ApiParam({ name: 'id', description: 'Coach UUID' })
  @ApiResponse({
    status: 200,
    description: `Coach detail including:
- seatClass: seat class info
- seatsByRow: seats grouped by row number, each seat includes label, seatNumber, col, kind (STANDARD/PREMIUM/ACCESSIBLE), status (AVAILABLE/HELD/BOOKED/BLOCKED), isWindow, isAisle, bedPosition (bed mode only), premiumFeeMinor
- seatStatusSummary: total/available/held/booked/blocked counts
- assignments: up to 5 most recent schedule assignments with origin/destination`,
  })
  @ApiResponse({ status: 404, description: 'Coach not found' })
  getCoach(@Param('id') id: string) { return this.service.getCoach(id); }

  @Post('coaches')
  @ApiOperation({ summary: 'Register a new physical coach and auto-generate its seats from arrangement config' })
  @ApiBody({ type: CreateCoachDto })
  @ApiResponse({ status: 201, description: 'Coach created with seats auto-generated from mode + arrangement + totalUnits' })
  @ApiResponse({ status: 400, description: 'Invalid arrangement format' })
  createCoach(@Body() dto: CreateCoachDto) { return this.service.createCoach(dto); }

  @Patch('coaches/:id')
  @ApiOperation({ summary: 'Update coach properties (label, mode, arrangement, etc.)' })
  @ApiParam({ name: 'id', description: 'Coach UUID' })
  @ApiBody({ type: UpdateCoachDto })
  @ApiResponse({ status: 200, description: 'Coach updated' })
  @ApiResponse({ status: 404, description: 'Coach not found' })
  updateCoach(@Param('id') id: string, @Body() dto: UpdateCoachDto) { return this.service.updateCoach(id, dto); }

  @Delete('trains/:id')
  @ApiOperation({ summary: 'Delete a train service' })
  @ApiParam({ name: 'id', description: 'Train UUID' })
  @ApiResponse({ status: 200, description: 'Train deleted' })
  @ApiResponse({ status: 404, description: 'Train not found' })
  deleteTrain(@Param('id') id: string) { return this.service.deleteTrain(id); }

  @Delete('coaches/:id')
  @ApiOperation({ summary: 'Delete a coach' })
  @ApiParam({ name: 'id', description: 'Coach UUID' })
  @ApiResponse({ status: 200, description: 'Coach deleted' })
  @ApiResponse({ status: 404, description: 'Coach not found' })
  deleteCoach(@Param('id') id: string) { return this.service.deleteCoach(id); }

  @Post('assignments')
  @ApiOperation({ summary: 'Assign a physical coach to a train schedule at a given position' })
  @ApiBody({ type: AssignCoachDto })
  @ApiResponse({ status: 201, description: 'CoachAssignment created' })
  @ApiResponse({ status: 404, description: 'Schedule or coach not found' })
  assignCoach(@Body() dto: AssignCoachDto) { return this.service.assignCoach(dto); }

  @Delete('assignments/:id')
  @ApiOperation({ summary: 'Remove a coach assignment from a schedule' })
  @ApiParam({ name: 'id', description: 'CoachAssignment UUID' })
  @ApiResponse({ status: 200, description: 'Assignment removed' })
  @ApiResponse({ status: 404, description: 'Assignment not found' })
  removeAssignment(@Param('id') id: string) { return this.service.removeAssignment(id); }

  @Post('seats/batch')
  @ApiOperation({ summary: 'Batch-generate seats for a coach (rows × cols)' })
  @ApiBody({ type: CreateSeatBatchDto })
  @ApiResponse({ status: 201, description: 'Returns count of seats created' })
  @ApiResponse({ status: 404, description: 'Coach not found' })
  createSeatBatch(@Body() dto: CreateSeatBatchDto) { return this.service.createSeatBatch(dto); }

  @Get('analytics')
  @ApiOperation({ summary: 'Fleet analytics: train count, schedule count, seat occupancy rate' })
  @ApiResponse({ status: 200, description: 'Returns totalTrains, totalSchedules, totalSeats, bookedSeats, occupancyRate' })
  getAnalytics() { return this.service.getAnalytics(); }
}
