import { IsString, IsEnum, IsNumber, IsOptional, IsUUID, Matches } from 'class-validator';
import { Transform } from 'class-transformer';
import {
  FuelType,
  VehicleAvailability,
  VehicleOwnership,
  VehicleStatus,
} from '../entities/vehicle.entity';

/**
 * A vehicle plate is two or three letters, a hyphen, then two to six digits —
 * e.g. ET-9875 or AA-8642. Kept in one place so plate, power-plate and trailer
 * all match and the message stays consistent.
 */
export const VEHICLE_PLATE_REGEX = /^[A-Z]{2,3}-\d{2,6}$/;
export const VEHICLE_PLATE_MESSAGE =
  'must be letters and numbers like ET-9875 or AA-8642';

/**
 * Trim and upper-case a plate before validating, so "et-9875" is accepted. An
 * empty optional plate (trailer/power) becomes undefined so @IsOptional skips it
 * rather than failing the pattern.
 */
const normalizePlate = ({ value }: { value: unknown }) => {
  if (typeof value !== 'string') return value;
  const trimmed = value.trim().toUpperCase();
  return trimmed === '' ? undefined : trimmed;
};

export class CreateVehicleDto {
  @Transform(normalizePlate)
  @Matches(VEHICLE_PLATE_REGEX, { message: `Plate number ${VEHICLE_PLATE_MESSAGE}` })
  @IsString()
  plateNumber!: string;

  /** Truck configuration from `freight.truck_types` — drives capacity and whether a trailer plate applies. */
  @IsUUID()
  truckTypeId!: string;

  @IsString()
  manufacturer!: string;

  @IsString()
  model!: string;

  @IsNumber()
  year!: number;

  @IsEnum(FuelType)
  fuelType!: FuelType;

  /** Defaults to the truck type's capacity when omitted. */
  @IsOptional()
  @IsNumber()
  capacity?: number;

  @IsOptional()
  @IsString()
  vin?: string;

  @IsOptional()
  @IsEnum(VehicleOwnership)
  ownership?: VehicleOwnership;

  @IsEnum(VehicleStatus)
  status!: VehicleStatus;

  @IsOptional()
  @IsEnum(VehicleAvailability)
  availability?: VehicleAvailability;

  @IsOptional()
  @IsString()
  description?: string;

  @IsOptional()
  @IsUUID()
  assignedDriverId?: string;

  @IsOptional()
  @IsString()
  assignedDriverName?: string;

  @IsOptional()
  @IsString()
  code?: string;

  @IsOptional()
  @Transform(normalizePlate)
  @Matches(VEHICLE_PLATE_REGEX, { message: `Power plate number ${VEHICLE_PLATE_MESSAGE}` })
  @IsString()
  powerPlateNo?: string;

  @IsOptional()
  @Transform(normalizePlate)
  @Matches(VEHICLE_PLATE_REGEX, { message: `Trailer plate number ${VEHICLE_PLATE_MESSAGE}` })
  @IsString()
  trailerPlateNo?: string;

  @IsOptional()
  @IsNumber()
  estimatedDistanceKm?: number;

  @IsOptional()
  @IsNumber()
  actualDistanceKm?: number;

  @IsOptional()
  @IsUUID()
  locationId?: string;

  @IsOptional()
  @IsNumber()
  pricePerKm?: number;

  @IsOptional()
  @IsString()
  currency?: string;
}
