import { Body, Controller, Get, Param, Post, UseGuards, Query, Request, UnauthorizedException, Patch, Delete } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiResponse, ApiQuery } from '@nestjs/swagger';
import { PassengersService } from './passengers.service';
import { CreateTravelerProfileDto, CreateSavedRouteDto, VerifyFaydaDto, SavePassengersDto, RegisterPassengerDto } from './passengers.dto';
import { JwtGuard } from '../../common/jwt.guard';
import { IamGuard } from '../../common/iam-adapter';
import { VerifaydaService } from '../verifayda/verifayda.service';
import { OptionalJwtGuard } from '../verifayda/optional-jwt.guard';
import { PrismaService } from '../../common/prisma.service';

@ApiTags('Passengers')
@Controller('passengers')
export class PassengersController {
  constructor(
    private service: PassengersService,
    private verifaydaService: VerifaydaService,
    private prisma: PrismaService,
  ) {}

  @Get()
  @ApiOperation({ 
    summary: 'List all passengers with filters (Admin/Agent)',
    description: 'Returns paginated list of passengers with search filters'
  })
  @ApiQuery({ name: 'search', required: false, description: 'Search by name, email, or phone' })
  @ApiQuery({ name: 'verified', required: false, description: 'Filter by verification status' })
  @ApiQuery({ name: 'page', required: false, description: 'Page number' })
  @ApiQuery({ name: 'pageSize', required: false, description: 'Items per page' })
  findAll(
    @Query('search') search?: string,
    @Query('verified') verified?: string,
    @Query('page') page?: string,
    @Query('pageSize') pageSize?: string,
  ) {
    return this.service.findAll({ 
      search, 
      verified: verified ? verified === 'true' : undefined, 
      page: page ? parseInt(page) : 1, 
      pageSize: pageSize ? parseInt(pageSize) : 20 
    });
  }

  @Get('me')
  @UseGuards(JwtGuard)
  @ApiBearerAuth('JWT-auth')
  @ApiOperation({ 
    summary: 'Get current passenger profile',
    description: 'Returns complete profile for authenticated passenger including passport details and verification status. Returns null if no passenger profile exists.'
  })
  @ApiResponse({ 
    status: 200, 
    description: 'Passenger profile retrieved successfully or null if not found'
  })
  @ApiResponse({ status: 401, description: 'Unauthorized - Invalid or missing token' })
  async getMe(@Request() req: any) {
    if (!req.user || !req.user.userId) {
      throw new UnauthorizedException('User not authenticated');
    }

    try {
      const user = await this.prisma.user.findUnique({
        where: { id: req.user.userId },
        include: { 
          passenger: true,
        },
      });

      if (!user || !user.passenger) {
        return null;
      }

      return this.service.getProfile(user.passenger.id);
    } catch (error) {
      // If profile lookup fails for any reason, return null to allow app to continue
      return null;
    }
  }

  @Get(':id/profile')
  @UseGuards(JwtGuard)
  @ApiBearerAuth('JWT-auth')
  @ApiOperation({ summary: 'Get passenger profile' })
  getProfile(@Param('id') id: string) {
    return this.service.getProfile(id);
  }

  @Get(':id/stats')
  @UseGuards(JwtGuard)
  @ApiBearerAuth('JWT-auth')
  @ApiOperation({ summary: 'Get passenger stats' })
  getStats(@Param('id') id: string) {
    return this.service.getStats(id);
  }

  @Post('verify-fayda')
  @ApiOperation({
    summary: 'Verify Ethiopian national ID via Verifayda 2.0',
    description: `**Standalone endpoint for pre-verification of Ethiopian national IDs**

---

### Purpose
Pre-verify national ID to auto-fill passenger registration form before submission.

---

### Flow

1. User enters national ID in form

2. Frontend calls \`POST /passengers/verify-fayda\`

3. API queries Verifayda 2.0 government database

4. Returns verified passenger data (name, DOB, gender)

5. Frontend auto-fills form with verified data

6. User submits form via \`POST /passengers/register\`

---

### Features
- Real-time verification via Verifayda 2.0 API
- Retrieves verified data: name, date of birth, gender, nationality
- **National IDs NOT stored** (policy compliant)
- Only for Ethiopian nationals with national ID
- Non-Ethiopians use passport (no verification)

---

### Important Notes
- This is a **read-only** verification endpoint
- Does NOT save passenger data to database
- Use \`POST /passengers/register\` to actually register
- Falls back to manual entry if Verifayda disabled or fails

---

### Authentication
- **Public endpoint** (no authentication required)
- Can be called before login/registration`,
  })
  @ApiResponse({ 
    status: 200, 
    description: 'Verification successful with passenger data',
    schema: {
      example: {
        verified: true,
        passengerData: {
          fullName: 'Abebe Kebede',
          dateOfBirth: '1985-03-15T00:00:00.000Z',
          gender: 'Male',
          nationality: 'Ethiopian'
        }
      }
    }
  })
  @ApiResponse({ status: 400, description: 'Verification failed or Verifayda disabled' })
  verifyFayda(@Body() dto: VerifyFaydaDto) {
    return this.verifaydaService.verifyNationalId(dto.nationalId);
  }

  @Post('register')
  @UseGuards(OptionalJwtGuard)
  @ApiBearerAuth('JWT-auth')
  @ApiOperation({
    summary: 'Universal passenger registration endpoint',
    description: `**Single endpoint for all passenger registration scenarios**

---

### Automatic Detection
The API automatically detects:
- **Passenger Type**: Ethiopian (nationalId) vs International (passportNumber)
- **Authentication**: Logged-in (JWT token) vs Guest (deviceId)
- **Verification**: Auto-attempts Fayda for Ethiopian nationals

---

### Scenarios Handled

#### 1. Guest Ethiopian Passenger
- Provide: \`nationalId\`, \`deviceId\`
- Behavior: Attempts Fayda verification → Saves to SavedPassengerProfile
- Response: \`verified: true/false\`, \`linked: false\`

#### 2. Guest International Passenger
- Provide: \`passportNumber\`, \`passportCountry\`, \`deviceId\`
- Behavior: No verification → Saves to SavedPassengerProfile
- Response: \`verified: false\`, \`linked: false\`

#### 3. Logged-in Ethiopian Passenger
- Provide: JWT token + \`nationalId\`
- Behavior: Attempts Fayda verification → Updates user profile
- Response: \`verified: true/false\`, \`linked: true\`

#### 4. Logged-in International Passenger
- Provide: JWT token + \`passportNumber\`, \`passportCountry\`
- Behavior: No verification → Updates user profile
- Response: \`verified: false\`, \`linked: true\`

---

### Authentication
- **Optional JWT Bearer Token** (OptionalJwtGuard)
- Token present → Links to user account
- No token → Saves as guest (requires deviceId)

---

### Benefits
- Single endpoint for all scenarios
- Auto-detects passenger type and flow
- Graceful fallback if Fayda fails
- Consistent response structure

---

### Replaces
- Manual verification + save flows`,
  })
  @ApiResponse({ 
    status: 201, 
    description: 'Passenger registered successfully',
    schema: {
      example: {
        id: 'uuid-123',
        passengerName: 'Abebe Kebede',
        dateOfBirth: '1985-03-15T00:00:00.000Z',
        nationality: 'Ethiopian',
        verified: true,
        linked: false,
        message: 'Passenger details saved for guest booking'
      }
    }
  })
  @ApiResponse({ 
    status: 400, 
    description: 'Validation error or verification failed',
    schema: {
      example: {
        statusCode: 400,
        message: 'Validation failed',
        error: 'Bad Request'
      }
    }
  })
  @ApiResponse({ 
    status: 401, 
    description: 'Invalid JWT token (only if token provided but invalid)' 
  })
  registerPassenger(@Body() dto: RegisterPassengerDto, @Request() req: any) {
    const userId = req.user?.userId;
    return this.service.registerPassenger({ ...dto, userId });
  }

  @Post('save-details')
  @ApiOperation({
    summary: 'Bulk save passenger details from booking flow',
    description: `**Endpoint for saving multiple passengers in a single booking**

---

### Purpose
Save all passenger details for a multi-passenger booking before proceeding to seat selection. Optimized for batch operations where all passengers are collected upfront.

---

### Use Cases
1. **Multi-passenger bookings** - Save all passengers in a single request
2. **Batch registration** - Admin/Agent registering multiple passengers at once
3. **Data preservation** - Save passenger data before proceeding to seat selection
4. **Guest bookings** - Multiple guests booking together

---

### Differences from /register
| Feature | /register | /save-details |
|---------|-----------|---------------|
| Purpose | Single passenger registration with optional verification | Bulk save multiple passengers |
| Passengers | One at a time | Multiple in array |
| Verification | Auto-attempts for Ethiopian nationals (if enabled) | No automatic verification |
| Use case | Individual registration flow | Booking flow with all passengers |
| Authentication | Optional JWT | Optional JWT |

---

### Response
Returns saved passenger details with generated IDs and confirmation.`,
  })
  @ApiResponse({ 
    status: 201, 
    description: 'All passenger details saved successfully',
    schema: {
      example: {
        count: 2,
        passengerIds: ['uuid-1', 'uuid-2'],
        passengers: [
          {
            id: 'uuid-1',
            passengerName: 'Abebe Kebede',
            dateOfBirth: '1985-03-15T00:00:00.000Z',
            nationality: 'Ethiopian',
            nationalId: 'ET123456789'
          },
          {
            id: 'uuid-2',
            passengerName: 'Sara Ketsela',
            dateOfBirth: '1990-08-22T00:00:00.000Z',
            nationality: 'Ethiopian',
            nationalId: 'ET987654321'
          }
        ],
        message: 'Passenger details saved successfully'
      }
    }
  })
  @ApiResponse({ status: 400, description: 'Validation error - passengers array required' })
  savePassengers(@Body() dto: SavePassengersDto) {
    return this.service.savePassengers(dto.passengers, dto.userId, dto.deviceId);
  }

  @Post('traveler-profiles')
  @UseGuards(JwtGuard)
  @ApiBearerAuth('JWT-auth')
  @ApiOperation({ summary: 'Add traveler profile (family member)' })
  createTravelerProfile(@Body() dto: CreateTravelerProfileDto) {
    return this.service.createTravelerProfile(dto);
  }

  @Get(':id/traveler-profiles')
  @UseGuards(JwtGuard)
  @ApiBearerAuth('JWT-auth')
  @ApiOperation({ summary: 'Get traveler profiles for passenger' })
  getTravelerProfiles(@Param('id') id: string) {
    return this.service.getTravelerProfiles(id);
  }

  @Post('saved-routes')
  @UseGuards(JwtGuard)
  @ApiBearerAuth('JWT-auth')
  @ApiOperation({ summary: 'Save a route' })
  createSavedRoute(@Body() dto: CreateSavedRouteDto) {
    return this.service.createSavedRoute(dto);
  }

  @Get(':id/saved-routes')
  @UseGuards(JwtGuard)
  @ApiBearerAuth('JWT-auth')
  @ApiOperation({ summary: 'Get saved routes' })
  getSavedRoutes(@Param('id') id: string) {
    return this.service.getSavedRoutes(id);
  }

  @Patch(':id')
  @ApiOperation({ 
    summary: 'Update passenger details',
    description: 'Updates passenger information for admin/agent operations'
  })
  @ApiResponse({ status: 200, description: 'Passenger updated successfully' })
  @ApiResponse({ status: 404, description: 'Passenger not found' })
  updatePassenger(@Param('id') id: string, @Body() dto: any) {
    return this.service.updatePassenger(id, dto);
  }

  @Delete(':id')
  @ApiOperation({ 
    summary: 'Delete passenger (admin only)',
    description: 'Permanently deletes a passenger record and associated data'
  })
  @ApiResponse({ status: 200, description: 'Passenger deleted successfully' })
  @ApiResponse({ status: 404, description: 'Passenger not found' })
  deletePassenger(@Param('id') id: string) {
    return this.service.deletePassenger(id);
  }

  @Get(':id/usage')
  @ApiOperation({ 
    summary: 'Check if passenger is in use',
    description: 'Returns list of modules/data that reference this passenger'
  })
  @ApiResponse({ status: 200, description: 'Usage information retrieved' })
  @ApiResponse({ status: 404, description: 'Passenger not found' })
  checkUsage(@Param('id') id: string) {
    return this.service.checkPassengerUsage(id);
  }
}
