import {
  IsOptional,
  IsString,
  IsUUID,
  IsArray,
  IsNumber,
  Min,
  MaxLength,
  IsEnum,
  ValidateNested,
} from 'class-validator';
import { Type } from 'class-transformer';
import { OpStatus } from '../../../common/constants/op-status';
import { ItemSupplierInputDto } from './supplier-input.dto';

export class AssignTransportItemDto {
  @IsUUID()
  @IsOptional()
  supplier_id?: string | null;

  /** Free-text supplier label — e.g. "Private Taxi", "Street cab". */
  @IsString()
  @IsOptional()
  @MaxLength(255)
  supplier_name_text?: string | null;

  /** Optional second supplier (e.g. transport + ticket broker split). */
  @IsUUID()
  @IsOptional()
  supplier_2_id?: string | null;

  @IsString()
  @IsOptional()
  @MaxLength(255)
  supplier_2_name_text?: string | null;

  @IsUUID()
  @IsOptional()
  driver_id?: string | null;

  /** Free-text driver name when the driver isn't a registered master. */
  @IsString()
  @IsOptional()
  @MaxLength(255)
  driver_name_text?: string | null;

  @IsString()
  @IsOptional()
  @MaxLength(20)
  driver_phone_text?: string | null;

  @IsUUID()
  @IsOptional()
  vehicle_id?: string | null;

  /** Free-text vehicle number / plate when not a registered master. */
  @IsString()
  @IsOptional()
  @MaxLength(50)
  vehicle_no_text?: string | null;

  @IsString()
  @IsOptional()
  @MaxLength(10)
  pickup_time?: string | null;

  /** Drop-off time at the destination (HH:MM). Paired with
   *  pickup_time on both the quote and the booking sides. */
  @IsString()
  @IsOptional()
  @MaxLength(10)
  dropoff_time?: string | null;

  /** Return-leg pickup time for two-way routes (HH:MM). Ignored
   *  client-side for one-way trips. */
  @IsString()
  @IsOptional()
  @MaxLength(10)
  return_pickup_time?: string | null;

  @IsString()
  @IsOptional()
  @MaxLength(500)
  pickup_address?: string | null;

  @IsString()
  @IsOptional()
  @MaxLength(500)
  dropoff_address?: string | null;

  // Planner-row editable fields — autosaved on blur from Movement
  // Chart → Planner tab. These also round-trip through the same
  // assignTransportItem service method.
  @IsNumber() @IsOptional() @Min(1) quantity?: number;
  @IsNumber() @IsOptional() unit_price?: number;
  @IsNumber() @IsOptional() subtotal?: number;
  /**
   * Per-trip actual supplier cost — Movement Chart Cost cell binds
   * this. Snapshotted from the matching Floor Price at booking-create;
   * ops can override on the day when reality differs (Ola/Uber sub,
   * surge, partial cancel). Null = "use the booked-time floor".
   * Internal margin only; never touches the customer-facing selling
   * (unit_price / subtotal).
   */
  @IsNumber() @Min(0) @IsOptional() actual_supplier_cost?: number | null;
  @IsString() @IsOptional() @MaxLength(1000) notes?: string | null;
  // Pickup + drop-off-specific remarks — separate from `notes` so
  // ops can split responsibilities (driver sees pickup_notes, hotel
  // desk sees dropoff_notes). Planner grid surfaces both in the
  // sub-row under the address cells.
  @IsString() @IsOptional() @MaxLength(1000) pickup_notes?: string | null;
  @IsString() @IsOptional() @MaxLength(1000) dropoff_notes?: string | null;
  @IsUUID() @IsOptional() vehicle_type_id?: string | null;

  // Per-row pax override for partial cancellations. Null explicitly
  // clears an override; omitted ⇒ unchanged.
  @IsNumber() @IsOptional() @Min(0) adults_override?: number | null;
  @IsNumber() @IsOptional() @Min(0) children_override?: number | null;

  // Operational status — validated enum, service layer enforces
  // transitions (see OP_STATUS_TRANSITIONS).
  @IsEnum(OpStatus) @IsOptional() op_status?: OpStatus;

  /** Multi-supplier assignment — Phase 3 of the junction refactor
   *  (migration 1784000). Same semantics as BulkAssignTransportItemDto
   *  — see docstring on the bulk variant. */
  @IsArray()
  @IsOptional()
  @ValidateNested({ each: true })
  @Type(() => ItemSupplierInputDto)
  suppliers?: ItemSupplierInputDto[];
}

export class BulkAssignTransportItemDto {
  @IsArray()
  @IsUUID('4', { each: true })
  item_ids: string[];

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

  @IsString()
  @IsOptional()
  @MaxLength(255)
  supplier_name_text?: string | null;

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

  @IsString()
  @IsOptional()
  @MaxLength(255)
  driver_name_text?: string | null;

  @IsString()
  @IsOptional()
  @MaxLength(20)
  driver_phone_text?: string | null;

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

  @IsString()
  @IsOptional()
  @MaxLength(50)
  vehicle_no_text?: string | null;

  /** Multi-supplier assignment — Phase 3 of the junction refactor
   *  (migration 1784000). When present, the service treats this as
   *  the source of truth: junction rows are replaced to match, and
   *  the legacy supplier_id / supplier_2_id columns are mirrored
   *  from the first two entries for read-side compat. When absent
   *  (legacy clients), the existing single-supplier flow runs and
   *  the syncItemSuppliersFromColumns dual-write helper keeps the
   *  junction fresh. */
  @IsArray()
  @IsOptional()
  @ValidateNested({ each: true })
  @Type(() => ItemSupplierInputDto)
  suppliers?: ItemSupplierInputDto[];
}
