import { IsString, IsOptional, IsInt, IsBoolean, IsArray, IsDateString, Min, ValidateNested, IsUUID, IsPositive } from 'class-validator';
import { Type } from 'class-transformer';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

export class CreatePriceTierDto {
  @ApiPropertyOptional({ description: 'SeatClass ID to link this tier to a specific seat class' })
  @IsOptional() @IsUUID() seatClassId?: string;

  @ApiProperty({ example: 'HSC' })
  @IsString() seatType: string;

  @ApiProperty({ example: 'Regular Seat (HSC)' })
  @IsString() label: string;

  @ApiProperty({ example: 1023200 })
  @IsInt() @Min(0) priceMinor: number;

  @ApiProperty({ example: 100 })
  @IsInt() @Min(0) availableSeats: number;
}

export class CreateInquiryDto {
  @ApiProperty() @IsUUID() packageId: string;
  @ApiPropertyOptional() @IsOptional() @IsUUID() priceTierId?: string;
  @ApiProperty({ example: 2 }) @IsInt() @Min(1) travelerCount: number;
  @ApiProperty() @IsString() contactName: string;
  @ApiPropertyOptional() @IsOptional() @IsString() contactEmail?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() contactPhone?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() notes?: string;
}

export class UpdateInquiryStatusDto {
  @ApiProperty({ example: 'CONTACTED' }) @IsString() status: string;
}

export class UpdatePriceTierDto {
  @ApiPropertyOptional() @IsOptional() @IsUUID() seatClassId?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() seatType?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() label?: string;
  @ApiPropertyOptional() @IsOptional() @IsInt() @Min(0) priceMinor?: number;
  @ApiPropertyOptional() @IsOptional() @IsInt() @Min(0) availableSeats?: number;
}

export class CreatePackageDto {
  @ApiProperty({ example: 'KULUBBI-2025' })
  @IsString() code: string;

  @ApiProperty({ example: 'Kulubbi Gabriel Pilgrimage Package' })
  @IsString() name: string;

  @ApiPropertyOptional()
  @IsOptional() @IsString() description?: string;

  @ApiProperty() @IsUUID() outboundScheduleId: string;
  @ApiProperty() @IsUUID() returnScheduleId: string;
  @ApiProperty() @IsUUID() originStationId: string;
  @ApiProperty() @IsUUID() destinationStationId: string;

  @ApiProperty({ example: '2025-07-24T07:00:00Z' })
  @IsDateString() boardingTime: string;

  @ApiProperty({ example: '2025-07-24T09:00:00Z' })
  @IsDateString() departureTime: string;

  @ApiProperty({ example: '2025-07-25T06:00:00Z' })
  @IsDateString() arrivalTime: string;

  @ApiProperty({ example: 912 })
  @IsInt() @Min(1) totalCapacity: number;

  @ApiPropertyOptional({ example: '1 Locomotive + 2SBC + 2HBC + 6HSC' })
  @IsOptional() @IsString() coachConfiguration?: string;

  @ApiProperty({ type: [String] })
  @IsArray() @IsString({ each: true }) includedServices: string[];

  @ApiPropertyOptional() @IsOptional() @IsBoolean() busTransferIncluded?: boolean;
  @ApiPropertyOptional() @IsOptional() @IsString() busTransferRoute?: string;

  @ApiProperty({ example: '2025-07-01T00:00:00Z' })
  @IsDateString() validFrom: string;

  @ApiProperty({ example: '2025-07-24T09:00:00Z' })
  @IsDateString() validUntil: string;

  @ApiProperty({ type: [CreatePriceTierDto] })
  @IsArray() @ValidateNested({ each: true }) @Type(() => CreatePriceTierDto)
  priceTiers: CreatePriceTierDto[];
}

export class BookPackagePassengerDto {
  @ApiProperty() @IsString() passengerName: string;
  @ApiPropertyOptional() @IsOptional() @IsDateString() dateOfBirth?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() idDocumentType?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() idDocumentNumber?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() passportNumber?: string;
  @ApiPropertyOptional() @IsOptional() @IsString() passportCountry?: string;
}

export class PackageBookingContextDto {
  @ApiProperty() @IsUUID() tierId: string;
  @ApiProperty({ example: 1 }) @IsInt() @IsPositive() adultCount: number;
  @ApiPropertyOptional({ example: 0 }) @IsOptional() @IsInt() @Min(0) childCount?: number;
}

export class BookPackageDto {
  @ApiProperty() @IsUUID() packageId: string;
  @ApiProperty() @IsUUID() priceTierId: string;

  @ApiPropertyOptional()
  @IsOptional() @IsString() displayCurrency?: string;

  @ApiPropertyOptional()
  @IsOptional() @IsString() contactEmail?: string;

  @ApiPropertyOptional()
  @IsOptional() @IsString() contactPhone?: string;

  @ApiPropertyOptional()
  @IsOptional() @IsString() promoCode?: string;

  @ApiProperty({ type: [BookPackagePassengerDto] })
  @IsArray() @ValidateNested({ each: true }) @Type(() => BookPackagePassengerDto)
  passengers: BookPackagePassengerDto[];

  /** Number of adult passengers (≥5 years). Derived from passengers array if omitted. */
  @ApiPropertyOptional({ example: 2 }) @IsOptional() @IsInt() @Min(1) adultCount?: number;

  /** Number of child passengers (<5 years). Derived from passengers array if omitted. */
  @ApiPropertyOptional({ example: 1 }) @IsOptional() @IsInt() @Min(0) childCount?: number;

  /**
   * SeatHold UUID returned by POST /seats/hold when the user selected seats on the
   * seatmap before proceeding to book. When provided, the hold's expiry is extended
   * to the payment deadline so the specific seat stays reserved on the seatmap for
   * the full payment window, matching the behaviour of normal bookings.
   */
  @ApiPropertyOptional({ description: 'SeatHold ID from seatmap selection' })
  @IsOptional() @IsUUID() holdId?: string;
}
