import { Body, Controller, Delete, Get, Param, Post, Patch, Query, UseGuards } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiResponse } from '@nestjs/swagger';
import { SeatsService } from './seats.service';
import { HoldSeatsDto } from './seats.dto';
import { JwtGuard } from '../../common/jwt.guard';
import { IamGuard } from '../../common/iam-adapter';

@ApiTags('Seats')
@Controller('seats')
export class SeatsController {
  constructor(private service: SeatsService) {}

  // ── Seat Map ──────────────────────────────────────────────────────────────
  @Get('seatmap/:scheduleId')
  @ApiOperation({ 
    summary: 'Get seat map with real-time availability by class',
    description: `Returns seat map for a schedule with availability by seat class:
- Economy Regular
- Economy Bed
- VIP Bed

Shows seat status: AVAILABLE, BOOKED, HELD, BLOCKED`
  })
  @ApiParam({ name: 'scheduleId', description: 'TrainSchedule UUID' })
  @ApiQuery({ name: 'coachId', required: false, description: 'Filter by coach UUID' })
  @ApiResponse({ status: 200, description: 'Returns coaches with seats and seat class info' })
  getSeatMap(@Param('scheduleId') scheduleId: string, @Query('coachId') coachId?: string) { return this.service.getSeatMap(scheduleId, coachId); }

  // ── Hold / Release ────────────────────────────────────────────────────────
  @Get('holds')
  @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth')
  @ApiOperation({
    summary: 'List active seat holds with full leg context',
    description: `Returns all non-expired holds enriched with:
- **schedule**: train number, departure/arrival, full route origin→destination
- **leg**: the specific origin→destination this hold covers (station name, code, stop sequence)
- **seats**: seat label, coach, seat class, row, col
- **ttlSeconds**: seconds remaining before the hold expires

This makes it clear which segment of the route each seat is held for, enabling segment-based reuse of the same seat on non-overlapping legs.`,
  })
  @ApiQuery({ name: 'scheduleId', required: false, description: 'Filter by TrainSchedule UUID' })
  @ApiQuery({ name: 'passengerId', required: false, description: 'Filter by Passenger UUID' })
  @ApiResponse({ status: 200, description: 'Active holds with schedule, leg, and seat details' })
  getHolds(
    @Query('scheduleId') scheduleId?: string,
    @Query('passengerId') passengerId?: string,
  ) { return this.service.getHolds(scheduleId, passengerId); }

  @Get('holds/:holdId')
  @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth')
  @ApiOperation({ summary: 'Get a single hold with full leg context' })
  @ApiParam({ name: 'holdId', description: 'SeatHold UUID' })
  @ApiResponse({ status: 200, description: 'Hold with schedule, leg, and seat details' })
  @ApiResponse({ status: 404, description: 'Hold not found' })
  getHold(@Param('holdId') holdId: string) { return this.service.getHold(holdId); }

  @Post('hold')
  @ApiOperation({ 
    summary: 'Hold seats for 15 minutes before booking (Public - Guest booking supported)',
    description: `Temporarily reserves seats for a passenger to complete booking.

**Features:**
- 15-minute hold duration
- Auto-release after expiry
- Prevents double booking
- Required before creating booking
- **Public endpoint** - No authentication required (supports guest booking)`
  })
  @ApiResponse({ status: 201, description: 'Seats held successfully with holdId' })
  @ApiResponse({ status: 409, description: 'One or more seats unavailable' })
  holdSeats(@Body() dto: HoldSeatsDto) { return this.service.holdSeats(dto); }

  @Delete('hold/:holdId')
  @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth')
  @ApiOperation({ summary: 'Release a seat hold' })
  @ApiParam({ name: 'holdId', description: 'Hold UUID' })
  @ApiResponse({ status: 200, description: 'Hold released' })
  @ApiResponse({ status: 404, description: 'Hold not found' })
  releaseHold(@Param('holdId') holdId: string) { return this.service.releaseHold(holdId); }

  // ── Seat Block / Unblock ───────────────────────────────────────────────────
  @Post(':seatId/block')
  @UseGuards(IamGuard) @ApiBearerAuth('IAM-auth')
  @ApiOperation({ summary: 'Block a seat (e.g., maintenance, damage)' })
  @ApiParam({ name: 'seatId', description: 'Seat UUID' })
  @ApiResponse({ status: 200, description: 'Seat blocked' })
  blockSeat(@Param('seatId') seatId: string, @Body() body: { reason: string }) {
    return this.service.blockSeat(seatId, body.reason);
  }

  @Delete(':seatId/block')
  @UseGuards(IamGuard) @ApiBearerAuth('IAM-auth')
  @ApiOperation({ summary: 'Unblock a seat' })
  @ApiParam({ name: 'seatId', description: 'Seat UUID' })
  @ApiResponse({ status: 200, description: 'Seat unblocked' })
  unblockSeat(@Param('seatId') seatId: string) {
    return this.service.unblockSeat(seatId);
  }

  // ── Remove Seat ────────────────────────────────────────────────────────────
  @Patch(':seatId/remove')
  @UseGuards(IamGuard) @ApiBearerAuth('IAM-auth')
  @ApiOperation({ summary: 'Remove a seat by marking with negative seatNumber' })
  @ApiParam({ name: 'seatId', description: 'Seat UUID' })
  @ApiResponse({ status: 200, description: 'Seat removed (seatNumber negated), shows as empty space' })
  @ApiResponse({ status: 404, description: 'Seat not found' })
  removeSeat(@Param('seatId') seatId: string) {
    return this.service.removeSeat(seatId);
  }

  @Patch(':seatId/undo-remove')
  @UseGuards(IamGuard) @ApiBearerAuth('IAM-auth')
  @ApiOperation({ summary: 'Undo seat removal by restoring original seatNumber' })
  @ApiParam({ name: 'seatId', description: 'Seat UUID' })
  @ApiResponse({ status: 200, description: 'Seat restored (negative seatNumber removed)' })
  @ApiResponse({ status: 404, description: 'Seat not found' })
  @ApiResponse({ status: 400, description: 'Seat is not removed' })
  undoRemoveSeat(@Param('seatId') seatId: string) {
    return this.service.undoRemoveSeat(seatId);
  }

  @Get('export/csv/:scheduleId') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Export seats as CSV' })
  async exportCSV(@Param('scheduleId') scheduleId: string) {
    const csv = await this.service.exportSeatsCSV(scheduleId);
    return { csv, filename: `seats-${scheduleId}.csv` };
  }

  @Post('import/preview') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Preview CSV import' })
  previewCSV(@Body() body: { csv: string }) {
    return this.service.previewSeatsCSV(body.csv);
  }

  @Post('import/commit') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Commit CSV import' })
  importCSV(@Body() body: { scheduleId: string; csv: string; commit: boolean }) {
    return this.service.importSeatsCSV(body.scheduleId, body.csv, body.commit);
  }
}
