import { Body, Controller, Get, Param, Post, Query, UseGuards, Delete, Patch } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger'; import { TicketsService } from './tickets.service'; import { JwtGuard } from '../../common/jwt.guard'; @ApiTags('Tickets') @Controller('tickets') export class TicketsController { constructor(private service: TicketsService) {} @Post('generate/:bookingId') @ApiOperation({ summary: 'Generate ticket for booking (confirmation page)', description: 'Creates a ticket when confirmation page is reached and permanently holds all associated seats with SeatBlock records.' }) generateTicket(@Param('bookingId') bookingId: string) { return this.service.generate(bookingId); } @Patch('update-seats/:bookingId') @ApiOperation({ summary: 'Update ticket seats before final confirmation', description: 'Allows users to change selected seats after ticket generation. Removes old seat blocks and creates new ones for updated seats.' }) updateSeats(@Param('bookingId') bookingId: string, @Body() body: { seatIds: string[] }) { return this.service.updateSeats(bookingId, body.seatIds); } @Get() @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'List all tickets with optional filters' }) listTickets( @Query('search') search?: string, @Query('status') status?: string, @Query('skip') skip?: string, @Query('take') take?: string, ) { return this.service.listTickets({ search, status, skip: skip ? parseInt(skip) : 0, take: take ? parseInt(take) : 50, }); } @Get(':bookingRef') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Get ticket with QR code and passenger details', description: `Returns ticket information including: - QR code for gate scanning - Barcode for offline validation - Passenger details (name, age category, nationality) - Journey details (origin, destination, seat, coach) - Fare breakdown with currency - PDF download link` }) getByRef(@Param('bookingRef') ref: string) { return this.service.getByRef(ref); } @Post(':bookingRef/validate') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Validate ticket at gate with audit logging', description: 'Validates ticket QR/barcode at station gate. Records validation in audit log with timestamp, gate, and validator.' }) validate( @Param('bookingRef') ref: string, @Body('validatorId') validatorId: string, @Body('gateId') gateId?: string ) { return this.service.validate(ref, validatorId, gateId); } @Get(':ticketId/validation-logs') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Get validation logs for ticket' }) getValidationLogs(@Param('ticketId') ticketId: string) { return this.service.getValidationLogs(ticketId); } @Get('offline/export') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Export tickets for offline validation' }) exportOfflineData(@Query('scheduleId') scheduleId: string) { return this.service.exportOfflineData(scheduleId); } @Post('validate/offline') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Batch import offline validations' }) validateOfflineBatch(@Body() body: { validations: any[] }) { return this.service.validateOfflineBatch(body.validations); } @Delete(':id') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Delete ticket (admin only)', description: 'Permanently deletes a ticket record and removes associated seat blocks' }) delete(@Param('id') id: string) { return this.service.delete(id); } }