import { generateObject } from "ai";
import { z } from "zod";
import { resolveModel, type AiConfig } from "../factory";

const PairingsOutputSchema = z.object({
  pairings: z.array(z.object({
    name: z.string(),
    role: z.enum(["starter", "side", "salad", "bread", "drink", "dessert", "sauce"]),
    description: z.string(),
    whyItPairs: z.string(),
    difficulty: z.enum(["easy", "medium", "hard"]),
    prepTimeMins: z.number().int().optional(),
  })),
});

export type PairingSuggestion = z.infer<typeof PairingsOutputSchema>["pairings"][number];

const LANG: Record<string, string> = { en: "English", fr: "French" };

export async function suggestPairings(
  recipe: {
    title: string;
    description?: string | null;
    difficulty?: string | null;
    dietaryTags?: Record<string, boolean> | null;
    ingredients: Array<{ rawName: string }>;
  },
  count = 4,
  config?: AiConfig & { userContext?: string },
  locale?: string
): Promise<PairingSuggestion[]> {
  const model = resolveModel(config);
  const lang = LANG[locale ?? "en"] ?? "English";

  const dietaryContext = recipe.dietaryTags
    ? Object.entries(recipe.dietaryTags).filter(([, v]) => v).map(([k]) => k).join(", ")
    : "";

  const { object } = await generateObject({
    model,
    schema: PairingsOutputSchema,
    system:
      `You are an expert chef and menu planner. Suggest complementary dishes that form a balanced, cohesive complete meal. Consider flavor profiles, cooking techniques, dietary restrictions, and cultural harmony. Avoid duplicating ingredients heavily. Suggest a balanced mix of roles (starter, sides, dessert, drinks). Respond in ${lang}.${config?.userContext ? `\n\nUser preferences and context:\n${config.userContext}` : ""}`,
    prompt: `Suggest ${count} dishes that pair well with this recipe to form a complete meal:\n\nRecipe: ${recipe.title}\n${recipe.description ? `Description: ${recipe.description}` : ""}\n${dietaryContext ? `Dietary: ${dietaryContext}` : ""}\nKey ingredients: ${recipe.ingredients.slice(0, 8).map((i) => i.rawName).join(", ")}`,
  });

  return object.pairings;
}
