import { generateObject } from "ai";
import { z } from "zod";
import { resolveModel, type AiConfig } from "../factory";
import { dietaryTagsSchema, ingredientSchema, stepSchema } from "./recipe-schema";

const RecipeOutputSchema = z.object({
  recipeType: z.enum(["dish", "drink"]).describe("\"drink\" only for a beverage/cocktail (no cooking step) — \"dish\" for anything else, including if unsure."),
  title: z.string(),
  description: z.string(),
  baseServings: z.number().int().min(1).max(100),
  prepMins: z.number().int().min(0).optional(),
  cookMins: z.number().int().min(0).optional(),
  difficulty: z.enum(["easy", "medium", "hard"]),
  dietaryTags: dietaryTagsSchema,
  ingredients: z.array(ingredientSchema(z.number())),
  steps: z.array(stepSchema),
});

export type GeneratedRecipe = z.infer<typeof RecipeOutputSchema>;

export async function generateRecipe(
  prompt: string,
  config?: AiConfig & { language?: string; difficulty?: "easy" | "medium" | "hard"; userContext?: string }
): Promise<GeneratedRecipe> {
  const model = resolveModel(config);
  const lang = config?.language ?? "en";
  const langInstruction = lang !== "en" ? ` Write the entire recipe (title, description, ingredient names, step instructions) in ${lang}.` : "";
  const difficultyInstruction = config?.difficulty ? ` The recipe must be ${config.difficulty} difficulty: ${{ easy: "simple techniques, minimal steps, common ingredients", medium: "moderate skill required, standard techniques", hard: "advanced techniques, multiple components, skilled cook required" }[config.difficulty]}.` : "";
  const userInstruction = config?.userContext ? `\n\nUser preferences and context:\n${config.userContext}` : "";

  const { object } = await generateObject({
    model,
    schema: RecipeOutputSchema,
    system:
      `You are a professional chef and culinary writer. Generate detailed, accurate, and delicious recipes. For ingredients: quantity must be a number only (e.g. 0.25, 1.5, 2), unit is a separate string (e.g. 'cup', 'tbsp', 'g', 'ml'). Never combine quantity and unit into one string. Include helpful notes for ingredients when relevant. Set recipeType to "drink" only for a beverage/cocktail with no cooking involved (mixing, shaking, stirring, blending) — default to "dish" whenever it's ambiguous. For a drink, never set cookMins, and default baseServings to 1 unless the request specifically asks for more than one serving/portion.${langInstruction}${difficultyInstruction}${userInstruction}`,
    prompt: `Create a recipe for: ${prompt}`,
  });

  // Belt-and-suspenders in case the model doesn't follow the drink-specific
  // instructions above — a drink has no "cook" step by definition, and a
  // model that ignores the 1-serving-by-default guidance would otherwise
  // silently produce a batch-sized drink recipe.
  if (object.recipeType === "drink") {
    return { ...object, cookMins: undefined };
  }
  return object;
}
