/**
 * Plan generation entry point.
 * Tries the agent path first, falls back to legacy pipeline.
 */

import { prisma } from "@/lib/prisma";
import { ApiError } from "@/lib/api";
import { runAgentPlanGeneration } from "./agentPlan";
import { runLegacyPlanGeneration, PLAN_PROGRESS_MESSAGES } from "./legacyPlan";
import { enrichTransitInfo, type EnrichDay } from "./transitEnrichment";
import type { TaggedIdea } from "./ideaSelection";

export interface PlanGenAvailableTime {
  date: string;
  startHour: number;
  endHour: number;
}

export interface PlanGenResult {
  id: string;
  days: { date: string; items: unknown[]; summary: string }[];
  createdAt: string;
}

export async function runPlanGeneration(
  roomId: string,
  userId: string,
  availableTime: PlanGenAvailableTime,
  onProgress?: (message: string) => void,
): Promise<PlanGenResult> {
  // 1. Fetch room & ideas
  const room = await prisma.blindBoxRoom.findUnique({ where: { id: roomId } });
  if (!room) throw new ApiError("房间不存在", 404);
  if (!room.lat || !room.lng) {
    throw new ApiError("请先设置房间位置", 400);
  }

  onProgress?.(PLAN_PROGRESS_MESSAGES.analyzing);

  const allIdeas = await prisma.blindBoxIdea.findMany({
    where: { roomId, status: "in_pool", category: { not: null } },
    select: {
      id: true,
      content: true,
      category: true,
      timeSlot: true,
      estimatedMinutes: true,
      searchQuery: true,
      searchType: true,
      costLevel: true,
      intensity: true,
      needsBooking: true,
    },
  });

  const taggedIdeas: TaggedIdea[] = allIdeas.filter(
    (i): i is TaggedIdea =>
      !!i.category &&
      !!i.timeSlot &&
      !!i.searchQuery &&
      !!i.searchType &&
      typeof i.estimatedMinutes === "number",
  );

  if (taggedIdeas.length < 2) {
    throw new ApiError("盒子里至少需要 2 个已标记的想法才能生成计划", 400);
  }

  // 2. Try agent path, fallback to legacy
  let days: { date: string; items: unknown[]; summary: string }[];

  try {
    const agentResult = await runAgentPlanGeneration(
      { lat: room.lat, lng: room.lng, city: room.city ?? "" },
      taggedIdeas,
      availableTime,
      onProgress,
    );
    days = agentResult.days;
  } catch (e) {
    console.error("runAgentPlanGeneration failed, falling back to legacy:", e);
    onProgress?.("使用备用方案规划...");
    const legacyResult = await runLegacyPlanGeneration(
      { lat: room.lat, lng: room.lng },
      taggedIdeas,
      availableTime,
      onProgress,
    );
    days = legacyResult.days;
  }

  // 3. Enrich transit info (best-effort)
  onProgress?.("正在查询交通信息...");
  await enrichTransitInfo(
    days as EnrichDay[],
    room.city ?? "上海",
    room.lat,
    room.lng,
  );

  // 4. Save to DB
  const plan = await prisma.weekendPlan.create({
    data: {
      roomId,
      userId,
      planData: JSON.stringify({ days }),
    },
  });

  return {
    id: plan.id,
    days,
    createdAt: plan.createdAt.toISOString(),
  };
}
