import {
  IsString,
  IsUUID,
  IsOptional,
  ValidateNested,
  IsArray,
  IsEmail,
  Matches,
  MinLength,
} from 'class-validator';
import { Type } from 'class-transformer';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

export class AddressDto {
  @ApiProperty({ example: '123 Main Street' })
  @IsString()
  @MinLength(5, { message: 'Street must be at least 5 characters' })
  street: string;

  @ApiProperty({ example: 'Rotterdam' })
  @IsString()
  @MinLength(2, { message: 'City must be at least 2 characters' })
  city: string;

  @ApiProperty({ example: '3000 AB' })
  @IsString()
  postalCode: string;

  @ApiProperty({ example: 'NL', description: 'ISO 3166-1 alpha-2 country code' })
  @IsString()
  @Matches(/^[A-Z]{2}$/, { message: 'Country must be a valid 2-letter ISO country code' })
  country: string;
}

export class PartyDto {
  @ApiProperty({ example: 'Acme Corporation' })
  @IsString()
  @MinLength(2, { message: 'Name must be at least 2 characters' })
  name: string;

  @ApiProperty({ type: AddressDto })
  @ValidateNested()
  @Type(() => AddressDto)
  address: AddressDto;

  @ApiProperty({ example: 'John Doe' })
  @IsString()
  @MinLength(2, { message: 'Contact name must be at least 2 characters' })
  contactName: string;

  @ApiProperty({ example: 'john.doe@acme.com' })
  @IsEmail({}, { message: 'Contact email must be a valid email address' })
  contactEmail: string;

  @ApiProperty({ example: '+31612345678' })
  @IsString()
  @Matches(/^\+?[1-9]\d{1,14}$/, {
    message: 'Contact phone must be a valid international phone number',
  })
  contactPhone: string;
}

export class ContainerDto {
  @ApiProperty({ example: '40HC', description: 'Container type' })
  @IsString()
  type: string;

  @ApiPropertyOptional({ example: 'ABCU1234567', description: 'Container number (11 characters)' })
  @IsOptional()
  @IsString()
  @Matches(/^[A-Z]{4}\d{7}$/, {
    message: 'Container number must be 4 letters followed by 7 digits',
  })
  containerNumber?: string;

  @ApiPropertyOptional({ example: 22000, description: 'Verified Gross Mass in kg' })
  @IsOptional()
  vgm?: number;

  @ApiPropertyOptional({
    example: -18,
    description: 'Temperature in Celsius (for reefer containers)',
  })
  @IsOptional()
  temperature?: number;

  @ApiPropertyOptional({ example: 'SEAL123456', description: 'Seal number' })
  @IsOptional()
  @IsString()
  sealNumber?: string;
}

export class CreateBookingRequestDto {
  @ApiProperty({
    example: '550e8400-e29b-41d4-a716-446655440000',
    description: 'Rate quote ID from previous search',
  })
  @IsUUID(4, { message: 'Rate quote ID must be a valid UUID' })
  rateQuoteId: string;

  @ApiProperty({ type: PartyDto, description: 'Shipper details' })
  @ValidateNested()
  @Type(() => PartyDto)
  shipper: PartyDto;

  @ApiProperty({ type: PartyDto, description: 'Consignee details' })
  @ValidateNested()
  @Type(() => PartyDto)
  consignee: PartyDto;

  @ApiProperty({
    example: 'Electronics and consumer goods',
    description: 'Cargo description',
  })
  @IsString()
  @MinLength(10, { message: 'Cargo description must be at least 10 characters' })
  cargoDescription: string;

  @ApiProperty({
    type: [ContainerDto],
    description: 'Container details (can be empty for initial booking)',
  })
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => ContainerDto)
  containers: ContainerDto[];

  @ApiPropertyOptional({
    example: 'Please handle with care. Delivery before 5 PM.',
    description: 'Special instructions for the carrier',
  })
  @IsOptional()
  @IsString()
  specialInstructions?: string;
}
