import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import { IsIn, IsNumber, IsOptional, IsString, IsUUID, MaxLength, Min } from 'class-validator';
import {
  RATE_APPLIES_TO,
  RATE_TRIGGERS,
  RATE_UNITS,
} from '../entities/rate.entity';

const TRADE_DIRECTIONS = ['IMPORT', 'EXPORT', 'BOTH'] as const;
const CURRENCIES = ['USD'] as const;
export const INTERCITY_KINDS = ['CONTAINER', 'BULK'] as const;
export const CARGO_KINDS = ['CONTAINER', 'BULK'] as const;

export class CreateRateDto {
  @ApiProperty({ enum: RATE_APPLIES_TO, description: 'Friendly category the rate applies to' })
  @IsIn([...RATE_APPLIES_TO])
  appliesTo!: string;

  @ApiProperty({
    enum: RATE_TRIGGERS,
    description: 'What makes this rate apply. ALWAYS = base freight; anything else is a surcharge.',
  })
  @IsIn([...RATE_TRIGGERS])
  trigger!: string;

  @ApiPropertyOptional({ description: 'FK to container_types.id — set for container/intercity-container rates' })
  @IsOptional()
  @IsUUID()
  containerTypeId?: string;

  @ApiPropertyOptional({ description: 'FK to cargo_types.id (bulk leaf commodity) — set for bulk/intercity-bulk rates' })
  @IsOptional()
  @IsUUID()
  cargoTypeId?: string;

  @ApiPropertyOptional({ enum: TRADE_DIRECTIONS, description: 'Trade direction. Null = direction-agnostic' })
  @IsOptional()
  @IsIn([...TRADE_DIRECTIONS])
  tradeDirection?: string;

  @ApiPropertyOptional({
    enum: INTERCITY_KINDS,
    description:
      'Whether an intercity rate covers containers or bulk. Required when appliesTo = INTERCITY; ignored otherwise. Not stored — it selects the INTERCITY_CONTAINER / INTERCITY_BULK rate type.',
  })
  @IsOptional()
  @IsIn([...INTERCITY_KINDS])
  intercityKind?: string;

  @ApiPropertyOptional({
    enum: CARGO_KINDS,
    description:
      'Whether a customs clearance rate covers containers or bulk. Required when trigger = CUSTOMS_CLEARANCE. Not stored — container fees carry a containerTypeId, bulk fees none.',
  })
  @IsOptional()
  @IsIn([...CARGO_KINDS])
  cargoKind?: string;

  @ApiPropertyOptional({
    description:
      'FK to yards.id — origin of the leg this rate prices. Required for base freight (bulk/container/intercity), rejected for surcharges and first/last mile.',
  })
  @IsOptional()
  @IsUUID()
  originYardId?: string;

  @ApiPropertyOptional({
    description:
      'FK to yards.id — destination of the leg this rate prices. Required for base freight (bulk/container/intercity), rejected for surcharges and first/last mile.',
  })
  @IsOptional()
  @IsUUID()
  destinationYardId?: string;

  @ApiPropertyOptional({ enum: CURRENCIES })
  @IsOptional()
  @IsIn([...CURRENCIES])
  currency?: string;

  @ApiProperty({ description: 'Numeric rate value', minimum: 0 })
  @IsNumber()
  @Min(0)
  @Transform(({ value }) => Number(value))
  rateValue!: number;

  @ApiPropertyOptional({
    enum: RATE_UNITS,
    description:
      'Unit basis for the rate. Optional for shapes with a forced unit (overweight is always PER_TON — the admin form hides the field and omits it); required otherwise.',
  })
  @IsOptional()
  @IsIn([...RATE_UNITS])
  rateUnit?: string;
}

export class SubmitRateForApprovalDto {
  @ApiPropertyOptional({ description: 'Optional note for the approval request', maxLength: 500 })
  @IsOptional()
  @IsString()
  @MaxLength(500)
  note?: string;
}
