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

export interface CargoContainerLine {
  containerSize: string;
  quantity: number;
}

/**
 * Cargo-aware availability query. Beyond the route yards, it carries the cargo
 * sizing so the service can check matching-wagon + train capacity per day. The
 * `containers` array is passed as a JSON string in the query string (GET) and
 * parsed here.
 */
export class AvailableDaysForCargoQueryDto {
  @ApiPropertyOptional({ format: 'uuid' })
  @IsOptional()
  @IsUUID()
  originYardId?: string;

  @ApiPropertyOptional({ format: 'uuid' })
  @IsOptional()
  @IsUUID()
  destinationYardId?: string;

  @ApiProperty({ enum: ['CONTAINER', 'BULK'] })
  @IsEnum(['CONTAINER', 'BULK'])
  freightType!: 'CONTAINER' | 'BULK';

  @ApiPropertyOptional({ description: 'Bulk cargo type code (e.g. COFFEE).' })
  @IsOptional()
  @IsString()
  cargoTypeCode?: string;

  @ApiPropertyOptional({ format: 'uuid', description: 'Bulk cargo type id (preferred over code).' })
  @IsOptional()
  @IsUUID()
  cargoTypeId?: string;

  @ApiPropertyOptional({
    description:
      'Container type ids as a JSON string array — enables the exact wagon-type compatibility gate (falls back to containerSize matching when absent).',
  })
  @IsOptional()
  @Transform(({ value }) => {
    if (value == null || value === '') return undefined;
    if (typeof value !== 'string') return value;
    try {
      return JSON.parse(value);
    } catch {
      return undefined;
    }
  })
  @IsArray()
  containerTypeIds?: string[];

  @ApiPropertyOptional({ description: 'Total bulk weight in tons.' })
  @IsOptional()
  @Transform(({ value }) => (value === '' || value == null ? undefined : Number(value)))
  @IsNumber()
  @Min(0)
  totalWeightTons?: number;

  @ApiPropertyOptional({
    description: 'Container lines as a JSON string: [{containerSize,quantity}].',
  })
  @IsOptional()
  @Transform(({ value }) => {
    if (value == null || value === '') return undefined;
    if (typeof value !== 'string') return value;
    try {
      return JSON.parse(value);
    } catch {
      return undefined;
    }
  })
  @IsArray()
  containers?: CargoContainerLine[];
}
