import {
  IsString,
  IsDateString,
  IsEnum,
  IsOptional,
  IsInt,
  Min,
  IsBoolean,
  Matches,
} from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';

export class RateSearchRequestDto {
  @ApiProperty({
    description: 'Origin port code (UN/LOCODE)',
    example: 'NLRTM',
    pattern: '^[A-Z]{5}$',
  })
  @IsString()
  @Matches(/^[A-Z]{5}$/, { message: 'Origin must be a valid 5-character UN/LOCODE (e.g., NLRTM)' })
  origin: string;

  @ApiProperty({
    description: 'Destination port code (UN/LOCODE)',
    example: 'CNSHA',
    pattern: '^[A-Z]{5}$',
  })
  @IsString()
  @Matches(/^[A-Z]{5}$/, {
    message: 'Destination must be a valid 5-character UN/LOCODE (e.g., CNSHA)',
  })
  destination: string;

  @ApiProperty({
    description: 'Container type',
    example: '40HC',
    enum: ['20DRY', '20HC', '40DRY', '40HC', '40REEFER', '45HC'],
  })
  @IsString()
  @IsEnum(['20DRY', '20HC', '40DRY', '40HC', '40REEFER', '45HC'], {
    message: 'Container type must be one of: 20DRY, 20HC, 40DRY, 40HC, 40REEFER, 45HC',
  })
  containerType: string;

  @ApiProperty({
    description: 'Shipping mode',
    example: 'FCL',
    enum: ['FCL', 'LCL'],
  })
  @IsEnum(['FCL', 'LCL'], { message: 'Mode must be either FCL or LCL' })
  mode: 'FCL' | 'LCL';

  @ApiProperty({
    description: 'Desired departure date (ISO 8601 format)',
    example: '2025-02-15',
  })
  @IsDateString({}, { message: 'Departure date must be a valid ISO 8601 date string' })
  departureDate: string;

  @ApiPropertyOptional({
    description: 'Number of containers',
    example: 2,
    minimum: 1,
    default: 1,
  })
  @IsOptional()
  @IsInt()
  @Min(1, { message: 'Quantity must be at least 1' })
  quantity?: number;

  @ApiPropertyOptional({
    description: 'Total cargo weight in kg',
    example: 20000,
    minimum: 0,
  })
  @IsOptional()
  @IsInt()
  @Min(0, { message: 'Weight must be non-negative' })
  weight?: number;

  @ApiPropertyOptional({
    description: 'Total cargo volume in cubic meters',
    example: 50.5,
    minimum: 0,
  })
  @IsOptional()
  @Min(0, { message: 'Volume must be non-negative' })
  volume?: number;

  @ApiPropertyOptional({
    description: 'Whether cargo is hazardous material',
    example: false,
    default: false,
  })
  @IsOptional()
  @IsBoolean()
  isHazmat?: boolean;

  @ApiPropertyOptional({
    description: 'IMO hazmat class (required if isHazmat is true)',
    example: '3',
    pattern: '^[1-9](\\.[1-9])?$',
  })
  @IsOptional()
  @IsString()
  @Matches(/^[1-9](\.[1-9])?$/, {
    message: 'IMO class must be in format X or X.Y (e.g., 3 or 3.1)',
  })
  imoClass?: string;
}
