import { generateObject } from "ai";
import { z } from "zod";
import { resolveModel, type AiConfig } from "../factory";
import { safeFetch } from "@/lib/validate-webhook-url";
import { dietaryTagsSchema, ingredientSchema, stepSchema } from "./recipe-schema";

const ImportedRecipeSchema = z.object({
  recipeType: z.enum(["dish", "drink"]).describe("\"drink\" only for a beverage/cocktail (no cooking step) — \"dish\" for anything else, including if unsure."),
  language: z.string().min(2).max(10).describe("ISO 639-1 code of the language the recipe content (title/ingredients/steps) is actually written in, e.g. \"en\", \"fr\" — the source page's language, not a language to translate into."),
  title: z.string(),
  description: z.string().optional(),
  baseServings: z.number().int().min(1).optional(),
  prepMins: z.number().int().min(0).optional(),
  cookMins: z.number().int().min(0).optional(),
  difficulty: z.enum(["easy", "medium", "hard"]).optional(),
  dietaryTags: dietaryTagsSchema.optional(),
  ingredients: z.array(ingredientSchema(z.string())),
  steps: z.array(stepSchema),
});

export type ImportedRecipe = z.infer<typeof ImportedRecipeSchema>;

export async function importFromUrl(url: string, config?: AiConfig): Promise<ImportedRecipe> {
  const res = await safeFetch(url, {
    headers: { "User-Agent": "Mozilla/5.0 (compatible; Epicure/1.0; recipe importer)" },
    signal: AbortSignal.timeout(10000),
  });

  if (!res.ok) throw new Error(`Failed to fetch URL: ${res.status}`);

  const html = await res.text();
  // strip scripts/styles, take first 30k chars to stay within context
  const cleaned = html
    .replace(/<script[\s\S]*?<\/script>/gi, "")
    .replace(/<style[\s\S]*?<\/style>/gi, "")
    .replace(/<[^>]+>/g, " ")
    .replace(/\s+/g, " ")
    .slice(0, 30000);

  const model = resolveModel(config);

  const { object } = await generateObject({
    model,
    schema: ImportedRecipeSchema,
    system:
      "You are an expert at extracting structured recipe data from web page text. Extract all recipe information accurately, in the same language as the source page — do not translate it. For ingredients, separate quantity, unit, and name. For steps, extract timer durations in seconds when mentioned. Set recipeType to \"drink\" only for a beverage/cocktail with no cooking involved — never set cookMins for a drink. Set language to the ISO 639-1 code of the page's actual language.",
    prompt: `Extract the recipe from this web page:\n\nURL: ${url}\n\nContent:\n${cleaned}`,
  });

  if (object.recipeType === "drink") {
    return { ...object, cookMins: undefined };
  }
  return object;
}
