///|
pub(all) enum ProblemVariant {
  CVRP
  VRPTW
} derive(Debug, Eq, ToJson)

///|
/// Distance functions supported by the instance builder.
pub(all) enum DistanceMetric {
  Euclidean
  RoundedEuclidean
  Manhattan
  Chebyshev
} derive(Debug, Eq, ToJson)

///|
pub(all) enum DestroyOperator {
  Random
  Shaw
  Worst
  Route
  Cluster
  TimeCritical
} derive(Debug, Eq, ToJson)

///|
pub(all) enum RepairOperator {
  Greedy
  Regret2
  DemandFirst
  TimeWindow
} derive(Debug, Eq, ToJson)

///|
pub struct Depot {
  x : Double
  y : Double
  ready_time : Double
  due_time : Double
} derive(Debug, ToJson)

///|
pub struct Customer {
  external_id : Int
  x : Double
  y : Double
  demand : Double
  ready_time : Double
  due_time : Double
  service_time : Double
} derive(Debug, ToJson)

///|
pub struct VehicleProfile {
  capacity : Double
  max_route_duration : Double
  fleet_size : Int
} derive(Debug, ToJson)

///|
pub struct VrpInstance {
  name : String
  variant : ProblemVariant
  metric : DistanceMetric
  depot : Depot
  vehicle : VehicleProfile
  customers : Array[Customer]
  distance_matrix : Array[Array[Double]]
} derive(Debug, ToJson)

///|
pub struct RouteMetrics {
  distance : Double
  duration : Double
  waiting_time : Double
  load : Double
  capacity_violation : Double
  time_violation : Double
  duration_violation : Double
  feasible : Bool
  arrivals : Array[Double]
} derive(Debug, ToJson)

///|
pub struct RoutePlan {
  stops : Array[Int]
  metrics : RouteMetrics
} derive(Debug, ToJson)

///|
pub struct Solution {
  routes : Array[RoutePlan]
  unassigned : Array[Int]
  total_distance : Double
  objective : Double
  feasible : Bool
  total_capacity_violation : Double
  total_time_violation : Double
  total_duration_violation : Double
} derive(Debug, ToJson)

///|
pub struct SolveConfig {
  iterations : Int
  local_search_rounds : Int
  segment_length : Int
  min_destroy : Int
  max_destroy : Int
  initial_temperature : Double
  cooling_rate : Double
  capacity_penalty : Double
  time_penalty : Double
  duration_penalty : Double
  unassigned_penalty : Double
} derive(Debug, ToJson)

///|
pub struct SolveStats {
  iterations : Int
  accepted_moves : Int
  improved_moves : Int
  local_improvements : Int
  evaluated_candidates : Int
  best_iteration : Int
  seed_objective : Double
  best_objective : Double
} derive(Debug, ToJson)

///|
pub struct SolveResult {
  instance : VrpInstance
  seed_solution : Solution
  best_solution : Solution
  stats : SolveStats
} derive(Debug, ToJson)

///|
pub struct CandidateInsertion {
  route_index : Int
  position : Int
  objective : Double
  solution : Solution
} derive(Debug, ToJson)