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

/** A requested container line (no per-unit data — GL enters that at booking). */
export class RequestContainerLineDto {
  @ApiProperty({ description: '"20ft" | "40ft" — must be in the contract scope' })
  @IsString()
  containerSize!: string;

  @ApiProperty({ minimum: 1 })
  @IsInt()
  @Min(1)
  @Transform(({ value }) => Number(value))
  quantity!: number;

  @ApiPropertyOptional({ minimum: 0 })
  @IsOptional()
  @IsInt()
  @Min(0)
  @Transform(({ value }) => Number(value))
  hazardousQuantity?: number;

  @ApiPropertyOptional({ minimum: 0 })
  @IsOptional()
  @IsInt()
  @Min(0)
  @Transform(({ value }) => Number(value))
  reeferQuantity?: number;
}

export class RequestBulkLineDto {
  @ApiPropertyOptional({ format: 'uuid' })
  @IsOptional()
  @IsUUID()
  cargoTypeId?: string | null;

  @ApiPropertyOptional({ minimum: 0 })
  @IsOptional()
  @IsNumber()
  @Min(0)
  @Transform(({ value }) => Number(value))
  cargoWeightTons?: number;

  @ApiPropertyOptional({ minimum: 0 })
  @IsOptional()
  @IsInt()
  @Min(0)
  @Transform(({ value }) => Number(value))
  itemCount?: number;

  @ApiPropertyOptional({ minimum: 0 })
  @IsOptional()
  @IsInt()
  @Min(0)
  @Transform(({ value }) => Number(value))
  hazardousQuantity?: number;
}

/** Customer's shipment request on a GENERAL customs contract. */
export class CreateBookingRequestDto {
  @ApiPropertyOptional({ format: 'uuid', description: 'Required for multi-route GENERAL.' })
  @IsOptional()
  @IsUUID()
  contractRouteId?: string;

  @ApiPropertyOptional({ description: 'Preferred shipment day (informational).' })
  @IsOptional()
  @IsString()
  scheduledDate?: string;

  @ApiPropertyOptional({ type: [RequestContainerLineDto] })
  @IsOptional()
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => RequestContainerLineDto)
  containers?: RequestContainerLineDto[];

  @ApiPropertyOptional({ type: RequestBulkLineDto })
  @IsOptional()
  @ValidateNested()
  @Type(() => RequestBulkLineDto)
  bulk?: RequestBulkLineDto;

  @ApiPropertyOptional({
    enum: ['ETB', 'USD'],
    description:
      'Billing currency for the shipment GL will book. Intercity is always ETB.',
  })
  @IsOptional()
  @IsIn(['ETB', 'USD'])
  paymentCurrency?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  notes?: string;
}

export class ReviewBookingRequestDto {
  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  note?: string;
}
