// Legacy deterministic pipeline for plan generation

import { searchPois } from "@/lib/amap";
import { generateSchedule, type ScheduleContext } from "@/lib/ai";
import { ApiError } from "@/lib/api";
import { selectIdeasForSlots, type TaggedIdea } from "./ideaSelection";
import type { PlanGenAvailableTime } from "./index";

export const PLAN_PROGRESS_MESSAGES = {
  analyzing: "正在分析你们的想法...",
  searching: "正在搜索地点...",
  planning: "正在规划路线...",
  planningDay: (day: string) => `正在规划${day}...`,
  almostDone: "快好了...",
} as const;

export async function runLegacyPlanGeneration(
  room: { lat: number; lng: number },
  taggedIdeas: TaggedIdea[],
  availableTime: PlanGenAvailableTime,
  onProgress?: (message: string) => void,
): Promise<{ days: { date: string; items: unknown[]; summary: string }[] }> {
  const at = availableTime;

  const dayConfigs: PlanGenAvailableTime[] =
    at.date === "整个周末"
      ? [
          { date: "周六", startHour: at.startHour, endHour: at.endHour },
          { date: "周日", startHour: at.startHour, endHour: at.endHour },
        ]
      : [at];

  const dayIdeas: TaggedIdea[][] = [];
  const usedIds = new Set<string>();
  for (const dayConfig of dayConfigs) {
    const remaining = taggedIdeas.filter((i) => !usedIds.has(i.id));
    if (remaining.length < 2) break;
    const selected = selectIdeasForSlots(remaining, dayConfig.endHour - dayConfig.startHour);
    for (const idea of selected) usedIds.add(idea.id);
    dayIdeas.push(selected);
  }
  const actualDayConfigs = dayConfigs.slice(0, dayIdeas.length);

  const allSelected = dayIdeas.flat();
  if (allSelected.length === 0) {
    throw new ApiError("无法从想法池中选出合适的活动", 400);
  }

  const uniqueByQuery = new Map<string, TaggedIdea>();
  for (const idea of allSelected) {
    if (!uniqueByQuery.has(idea.searchQuery)) uniqueByQuery.set(idea.searchQuery, idea);
  }

  onProgress?.(PLAN_PROGRESS_MESSAGES.searching);

  const brandPlaceQueries = [...uniqueByQuery.values()].filter((i) => i.searchType !== "category");
  const searchResults = await Promise.all(
    brandPlaceQueries.map(async (idea) => {
      try {
        const pois = await searchPois(idea.searchQuery, idea.searchType, room.lat, room.lng);
        return { query: idea.searchQuery, pois };
      } catch (e) {
        console.error(`searchPois failed for "${idea.searchQuery}":`, e);
        return { query: idea.searchQuery, pois: [] };
      }
    }),
  );

  const toCandidates = (pois: { name: string; address: string; lat: number; lng: number; rating?: number | null }[]) =>
    pois.map((p) => ({ ...p, rating: p.rating ?? undefined }));

  const candidates: ScheduleContext["candidates"] = {};
  for (const result of searchResults) {
    candidates[result.query] = toCandidates(result.pois);
  }

  const catQueries = [...uniqueByQuery.values()].filter((i) => i.searchType === "category");
  if (catQueries.length > 0) {
    const allPois = Object.values(candidates).flat();
    let anchorLat = room.lat;
    let anchorLng = room.lng;
    if (allPois.length > 0) {
      anchorLat = allPois.reduce((s, p) => s + p.lat, 0) / allPois.length;
      anchorLng = allPois.reduce((s, p) => s + p.lng, 0) / allPois.length;
    }
    const catResults = await Promise.all(
      catQueries.map(async (idea) => {
        try {
          const pois = await searchPois(idea.searchQuery, idea.searchType, anchorLat, anchorLng);
          return { query: idea.searchQuery, pois };
        } catch (e) {
          console.error(`searchPois (category) failed for "${idea.searchQuery}":`, e);
          return { query: idea.searchQuery, pois: [] };
        }
      }),
    );
    for (const result of catResults) {
      candidates[result.query] = toCandidates(result.pois);
    }
  }

  onProgress?.(PLAN_PROGRESS_MESSAGES.planning);

  const schedules = await Promise.all(
    actualDayConfigs.map((dayConfig, idx) => {
      onProgress?.(PLAN_PROGRESS_MESSAGES.planningDay(dayConfig.date));
      const ideas = dayIdeas[idx];
      const ctx: ScheduleContext = {
        ideas: ideas.map((i) => ({
          content: i.content,
          category: i.category,
          timeSlot: i.timeSlot,
          estimatedMinutes: i.estimatedMinutes,
          searchQuery: i.searchQuery,
          searchType: i.searchType,
          costLevel: i.costLevel ?? undefined,
          intensity: i.intensity ?? undefined,
          needsBooking: i.needsBooking ?? undefined,
        })),
        candidates,
        userLocation: { lat: room.lat, lng: room.lng },
        availableTime: dayConfig,
      };
      return generateSchedule(ctx);
    }),
  );

  const days = schedules
    .map((schedule, idx) =>
      schedule
        ? {
            date: actualDayConfigs[idx].date,
            items: schedule.items,
            summary: schedule.summary,
          }
        : null,
    )
    .filter((d): d is NonNullable<typeof d> => d !== null);

  if (days.length === 0) {
    throw new ApiError("AI 规划失败，请稍后重试", 500);
  }

  return { days };
}
