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

import {
  LOCOMOTIVE_STATUSES,
  LOCOMOTIVE_TYPES,
} from '../entities/locomotive.entity';

export class CreateLocomotiveDto {
  // Optional on input — the service auto-generates a sequential LOCO-NNN code
  // when none is supplied.
  @ApiPropertyOptional({ example: 'LOCO-001' })
  @IsOptional()
  @IsString()
  @MaxLength(32)
  code?: string;

  @ApiPropertyOptional()
  @IsOptional()
  @IsString()
  @MaxLength(100)
  name?: string;

  @ApiProperty({ enum: LOCOMOTIVE_TYPES })
  @IsIn([...LOCOMOTIVE_TYPES])
  locomotiveType!: string;

  @ApiProperty({ enum: LOCOMOTIVE_STATUSES })
  @IsIn([...LOCOMOTIVE_STATUSES])
  status!: string;

  @ApiPropertyOptional({ description: 'Current yard location' })
  @IsOptional()
  @IsUUID()
  currentYardId?: string;

  // Defaults to 2500 tons when omitted (see service).
  @ApiPropertyOptional({ example: 2500, default: 2500 })
  @IsOptional()
  @Transform(({ value }) => (value === '' || value == null ? undefined : Number(value)))
  @IsNumber()
  @Min(0)
  maxPullWeightTons?: number;

  @ApiProperty({ example: 760 })
  @Transform(({ value }) => Number(value))
  @IsNumber()
  @Min(0)
  maxTrainLengthMeters!: number;

  // Allowed deviation above maxPullWeightTons before scheduling blocks the train
  // (e.g. 90 lets a 3,500T-rated locomotive pull up to 3,590T). Omit/0 = strict cap.
  @ApiPropertyOptional({ example: 90 })
  @IsOptional()
  @Transform(({ value }) => (value === '' || value == null ? undefined : Number(value)))
  @IsNumber()
  @Min(0)
  overageToleranceTons?: number;

  // Allowed deviation above maxTrainLengthMeters before scheduling blocks the train.
  @ApiPropertyOptional({ example: 0 })
  @IsOptional()
  @Transform(({ value }) => (value === '' || value == null ? undefined : Number(value)))
  @IsNumber()
  @Min(0)
  overageToleranceMeters?: number;
}
