/** Physical dimensions used when deriving how many wagons a locomotive can pull. */
export type WagonTypeDimensions = {
  lengthMeters: number;
  capacityTons: number;
};

export type LocomotiveLimits = {
  maxPullWeightTons: number;
  maxTrainLengthMeters: number;
};

export type DerivedTrainCapacity = {
  maxWeightTons: number;
  maxLengthMeters: number;
  maxWagonSlots: number;
};

const DEFAULT_WAGON_LENGTH_M = 14;
const DEFAULT_WAGON_CAPACITY_T = 70;

/**
 * Derive train capacity from locomotive pull weight and train length.
 * Wagon count is NOT a fixed 53 — it is the minimum of:
 * - floor(maxLength / shortest wagon type length)
 * - floor(maxWeight / lightest wagon type capacity)
 */
export function deriveTrainCapacityFromLocomotive(
  locomotive: LocomotiveLimits,
  wagonTypes: WagonTypeDimensions[],
  ruleCaps?: { maxTrainWeightTons?: number; maxTrainLengthMeters?: number },
): DerivedTrainCapacity {
  const maxWeightTons = Math.min(
    Number(locomotive.maxPullWeightTons) || Infinity,
    ruleCaps?.maxTrainWeightTons ?? Infinity,
  );
  const maxLengthMeters = Math.min(
    Number(locomotive.maxTrainLengthMeters) || Infinity,
    ruleCaps?.maxTrainLengthMeters ?? Infinity,
  );

  const types =
    wagonTypes.length > 0
      ? wagonTypes
      : [{ lengthMeters: DEFAULT_WAGON_LENGTH_M, capacityTons: DEFAULT_WAGON_CAPACITY_T }];

  const minLength = Math.min(...types.map((w) => Number(w.lengthMeters) || DEFAULT_WAGON_LENGTH_M));
  const minCapacity = Math.min(
    ...types.map((w) => Number(w.capacityTons) || DEFAULT_WAGON_CAPACITY_T),
  );

  const byLength =
    minLength > 0 && Number.isFinite(maxLengthMeters)
      ? Math.floor(maxLengthMeters / minLength)
      : 0;
  const byWeight =
    minCapacity > 0 && Number.isFinite(maxWeightTons)
      ? Math.floor(maxWeightTons / minCapacity)
      : byLength;

  const maxWagonSlots = Math.max(0, Math.min(byLength, byWeight));

  return {
    maxWeightTons: Number.isFinite(maxWeightTons) ? maxWeightTons : MAX_FALLBACK_WEIGHT,
    maxLengthMeters: Number.isFinite(maxLengthMeters) ? maxLengthMeters : MAX_FALLBACK_LENGTH,
    maxWagonSlots,
  };
}

export const MAX_FALLBACK_WEIGHT = 3500;
export const MAX_FALLBACK_LENGTH = 760;

/** Per-booking train length from wagon count and freight-specific wagon type length. */
export function bookingTrainLengthMeters(
  freightType: string | null | undefined,
  wagonCount: number,
  lengths: { container: number; bulk: number },
): number {
  const perWagon = freightType === 'BULK' ? lengths.bulk : lengths.container;
  return wagonCount * perWagon;
}

export function wagonTypeDimensionsFromEntity(wt: {
  lengthMeters?: number | string | null;
  capacityTons?: number | string | null;
}): WagonTypeDimensions {
  return {
    lengthMeters: Number(wt.lengthMeters) || DEFAULT_WAGON_LENGTH_M,
    capacityTons: Number(wt.capacityTons) || DEFAULT_WAGON_CAPACITY_T,
  };
}
