import { TripCircuitDTO } from "@/shared/types/circuit";

/**
 * Function to remove duplicates from a list of trips
 * Prioritizes even weeks (P) when duplicates are found
 * 
 * Uses tripTitled to extract the days and time
 */
export function deduplicateTrips(trips: TripCircuitDTO[]): TripCircuitDTO[] {
  if (!trips || trips.length === 0) {
    return trips;
  }

  const uniqueTripsMap = new Map<string, TripCircuitDTO>();

  for (const trip of trips) {
    const key = createDeduplicationKey(trip);
    const existingTrip = uniqueTripsMap.get(key);
    
    if (!existingTrip) {
      uniqueTripsMap.set(key, trip);
    } else {
      if (shouldReplaceTrip(existingTrip, trip)) {
        const normalizedTrip: TripCircuitDTO = {
          ...trip,
          tripTitled: removeParityFromTripTitle(trip.tripTitled),
        };
        uniqueTripsMap.set(key, normalizedTrip);
      } else {
        const normalizedExistingTrip: TripCircuitDTO = {
          ...existingTrip,
          tripTitled: removeParityFromTripTitle(existingTrip.tripTitled),
        };
        uniqueTripsMap.set(key, normalizedExistingTrip);
      }
    }
  }

  return Array.from(uniqueTripsMap.values());
}

/**
 * Determines if the new trip should replace the existing one
 */
function shouldReplaceTrip(existingTrip: TripCircuitDTO, newTrip: TripCircuitDTO): boolean {
  const existingHasP = hasParity(existingTrip.tripTitled, 'P');
  const newHasP = hasParity(newTrip.tripTitled, 'P');
  
  if (newHasP && !existingHasP) {
    return true;
  }
  
  return false;
}

/**
 * Checks if a trip title contains a specific parity indicator
 */
function hasParity(tripTitled: string, parity: 'P' | 'I'): boolean {
  if (!tripTitled) return false;
  const parts = tripTitled.split('-');
  return parts.includes(parity);
}

/**
 * Creates a unique key to identify duplicate trips
 */
function createDeduplicationKey(trip: TripCircuitDTO): string {
  const tripTitledInfo = removeParityFromTripTitle(trip.tripTitled);
  const passengerIds = trip.passengerInfo
    .map(passenger => passenger.id)
    .sort()
    .join(',');

  return `${trip.circuitCode}-${trip.sensTrip}-${tripTitledInfo}-${passengerIds}`;
}

/**
 * Removes week parity indicators (P/I) from the trip title
 */
function removeParityFromTripTitle(tripTitled: string): string {
  if (!tripTitled) return tripTitled;
  const parts = tripTitled.split('-');
  const filtered = parts.filter(part => part !== 'P' && part !== 'I');
  return filtered.join('-');
}