import { UserPreferences } from "@/services/openai-service";

export interface Place {
  id: string;
  name: string;
  description?: string;
  latitude: number;
  longitude: number;
  category: string;
  priority: number;
  imageUrl?: string;
  rating?: number;
}

export function optimizeRoute(
  places: Place[],
  preferences: UserPreferences
): Place[] {
  if (places.length === 0) return [];
  
  const sortedByPriority = [...places].sort((a, b) => b.priority - a.priority);
  const optimizedByDistance = optimizeByDistance(sortedByPriority);
  
  // Here we could filter by time constraints if needed
  // const timeOptimized = filterByTimeConstraints(optimizedByDistance, preferences.duration);

  return optimizedByDistance;
}

function optimizeByDistance(places: Place[]): Place[] {
  if (places.length === 0) return [];
  const optimized: Place[] = [places[0]];
  const remaining = places.slice(1);

  while (remaining.length > 0) {
    const current = optimized[optimized.length - 1];
    const nearest = findNearestPlace(current, remaining);
    optimized.push(nearest);
    remaining.splice(remaining.indexOf(nearest), 1);
  }

  return optimized;
}

function findNearestPlace(from: Place, candidates: Place[]): Place {
  let nearest = candidates[0];
  let minDistance = calculateDistance(
    from.latitude,
    from.longitude,
    nearest.latitude,
    nearest.longitude
  );

  for (const candidate of candidates) {
    const distance = calculateDistance(
      from.latitude,
      from.longitude,
      candidate.latitude,
      candidate.longitude
    );
    if (distance < minDistance) {
      minDistance = distance;
      nearest = candidate;
    }
  }

  return nearest;
}

function calculateDistance(
  lat1: number,
  lon1: number,
  lat2: number,
  lon2: number
): number {
  const R = 6371;
  const dLat = toRad(lat2 - lat1);
  const dLon = toRad(lon2 - lon1);

  const a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(toRad(lat1)) *
      Math.cos(toRad(lat2)) *
      Math.sin(dLon / 2) *
      Math.sin(dLon / 2);

  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  return R * c;
}

function toRad(degrees: number): number {
  return degrees * (Math.PI / 180);
}
