export type VehicleCandidateSource = {
  vin: string;
  plate?: string;
  protocol?: string;
  protocols?: string[];
};

export type MergedVehicleCandidate<T extends VehicleCandidateSource> = T & {
  protocols: string[];
};

export function mergeVehicleCandidates<T extends VehicleCandidateSource>(
  vehicles: readonly T[]
): Array<MergedVehicleCandidate<T>> {
  const byVIN = new Map<string, MergedVehicleCandidate<T>>();

  for (const vehicle of vehicles) {
    const vin = vehicle.vin.trim().toUpperCase();
    if (!vin) continue;
    const incomingProtocols = new Set([
      ...(vehicle.protocols ?? []),
      vehicle.protocol ?? ''
    ].map((protocol) => protocol.trim()).filter(Boolean));
    const current = byVIN.get(vin);

    if (!current) {
      byVIN.set(vin, {
        ...vehicle,
        vin,
        protocols: [...incomingProtocols]
      });
      continue;
    }

    const protocols = new Set([...current.protocols, ...incomingProtocols]);
    byVIN.set(vin, {
      ...current,
      ...(!current.plate && vehicle.plate ? { plate: vehicle.plate } : {}),
      protocols: [...protocols]
    });
  }

  return [...byVIN.values()];
}
