import { createAamosClient } from "@app/ai-contracts";
import { SEED_INGREDIENTS } from "@app/database/seed";
import { createDatabase, closeDatabase, schema } from "@app/database";
import { runPipeline, type PipelineTarget, type PipelineIngredient } from "@app/recipe-generation";
import type { CanonicalIngredientLookup, SimilarityLookup, RecipeCandidate } from "@app/recipe-generation";
import { randomUUID } from "node:crypto";

const VALID_CUISINES = new Set([
  "swedish", "nordic", "italian", "french", "spanish", "greek", "thai",
  "chinese", "japanese", "korean", "vietnamese", "indian", "mexican",
  "american", "turkish", "lebanese", "moroccan", "middle_eastern", "international",
]);

function normalizeCuisine(raw: string | undefined): string {
  const c = (raw ?? "swedish").toLowerCase().replace(/[^a-z]/g, "_");
  if (VALID_CUISINES.has(c)) return c;
  if (c === "asian") return "international";
  if (c.includes("swedish") || c.includes("nordic")) return "swedish";
  if (c.includes("italian")) return "italian";
  if (c.includes("asian")) return "international";
  if (c.includes("japan")) return "japanese";
  if (c.includes("china")) return "chinese";
  if (c.includes("thai")) return "thai";
  if (c.includes("indian")) return "indian";
  if (c.includes("mexican")) return "mexican";
  if (c.includes("american")) return "american";
  if (c.includes("mediterranean")) return "greek";
  return "international";
}

const catalog: PipelineIngredient[] = SEED_INGREDIENTS.map((i) => ({
  id: i.id,
  nameSv: i.nameSv,
  category: i.category,
  defaultUnit: i.defaultUnit,
  isVegan: i.isVegan,
  isVegetarian: i.isVegetarian,
  containsGluten: i.containsGluten,
  containsLactose: i.containsLactose,
  allergens: i.allergens,
}));

const ingredientLookup: CanonicalIngredientLookup = {
  getById(id: string) {
    const ing = SEED_INGREDIENTS.find((i) => i.id === id);
    if (!ing) return undefined;
    return {
      id: ing.id,
      nutritionPer100: ing.nutritionPer100,
      defaultUnit: ing.defaultUnit,
      densityGPerMl: ing.densityGPerMl ?? null,
      gramsPerPiece: ing.gramsPerPiece ?? null,
      allergens: ing.allergens,
      isVegan: ing.isVegan,
      isVegetarian: ing.isVegetarian,
      containsGluten: ing.containsGluten,
      containsLactose: ing.containsLactose,
      isPork: ing.isPork,
      isBeef: ing.isBeef,
      isAlcohol: ing.isAlcohol,
    };
  },
};

const targets: PipelineTarget[] = [
  { mealType: "dinner", mainIngredientId: "chicken_breast", dietVariant: "standard", count: 2 },
  { mealType: "dinner", mainIngredientId: "minced_beef", dietVariant: "standard", count: 2 },
  { mealType: "dinner", mainIngredientId: "tofu", dietVariant: "vegan", count: 1 },
];

function inferDietTags(candidate: RecipeCandidate): string[] {
  const ings = candidate.ingredients.map((i) => ingredientLookup.getById(i.canonicalIngredientId)).filter(Boolean);
  const tags: string[] = [];
  const allVegan = ings.every((i) => i?.isVegan);
  const allVegetarian = ings.every((i) => i?.isVegetarian);
  const noGluten = ings.every((i) => !i?.containsGluten);
  const noLactose = ings.every((i) => !i?.containsLactose);
  if (allVegan) tags.push("vegan");
  else if (allVegetarian) tags.push("vegetarian");
  if (noGluten) tags.push("gluten_free");
  if (noLactose) tags.push("lactose_free");
  return tags;
}

async function main() {
  const dbUrl = process.env.DATABASE_URL;
  if (!dbUrl) throw new Error("DATABASE_URL saknas");
  const { db } = createDatabase(dbUrl);
  const client = createAamosClient(process.env);

  const existing = await db.query.recipes.findMany({ columns: { titleSv: true, slug: true } });
  const knownTitles = new Set(existing.map((r) => r.titleSv.toLowerCase().replace(/[^a-z0-9åäö]/g, " ")));
  const knownSlugs = new Set(existing.map((r) => r.slug));

  const similarityLookup: SimilarityLookup = {
    async hasSimilarity(title: string) {
      return knownTitles.has(title.toLowerCase().replace(/[^a-z0-9åäö]/g, " "));
    },
  };

  console.error("[scale-smoke-test] starting");
  const result = await runPipeline(
    client,
    targets,
    catalog,
    ingredientLookup,
    similarityLookup,
    { maxPrepTimeMinutes: 30, maxCookTimeMinutes: 45, portions: 4 },
  );

  console.error(`[scale-smoke-test] generated=${result.candidates.length} verified=${result.verifiedCount} unverified=${result.unverifiedCount} rejected=${result.rejectedCount}`);

  let seeded = 0;
  for (let i = 0; i < result.candidates.length; i++) {
    const candidate = result.candidates[i]!;
    const v = result.verificationResults[i]!;
    if (v.status !== "verified") continue;

    const slugBase = candidate.titleSv
      .toLowerCase()
      .normalize("NFD")
      .replace(/[\u0300-\u036f]/g, "")
      .replace(/[^a-z0-9]+/g, "-")
      .replace(/^-+|-+$/g, "");
    let slug = slugBase;
    if (knownSlugs.has(slug)) slug = `${slug}-${randomUUID().slice(0, 8)}`;
    knownSlugs.add(slug);

    const nutrition = v.nutritionPerPortion ?? { kcal: 0, proteinG: 0, carbsG: 0, fatG: 0, saturatedFatG: 0, fiberG: 0, sugarG: 0, saltG: 0 };

    await db.insert(schema.recipes).values({
      id: randomUUID(),
      slug,
      titleSv: candidate.titleSv,
      descriptionSv: candidate.descriptionSv,
      cuisine: normalizeCuisine(candidate.cuisine),
      mealTypes: candidate.mealTypes,
      tags: [],
      methods: [],
      equipment: [],
      prepTimeMinutes: candidate.prepTimeMinutes,
      cookTimeMinutes: candidate.cookTimeMinutes,
      totalTimeMinutes: candidate.totalTimeMinutes,
      portions: candidate.portions,
      nutritionPerPortion: nutrition,
      allergens: v.allergens,
      spiceLevel: candidate.spiceLevel,
      storageGuidanceSv: candidate.storageGuidanceSv ?? null,
      mealPrepFriendly: candidate.mealPrepFriendly,
      freezerFriendly: candidate.freezerFriendly,
      dna: {
        cuisine: normalizeCuisine(candidate.cuisine),
        protein: candidate.ingredients.find((i) => ["chicken_breast", "chicken_thigh", "minced_beef", "minced_mixed", "salmon", "cod", "shrimp", "tofu", "red_lentils"].includes(i.canonicalIngredientId))?.canonicalIngredientId,
        carbohydrate: candidate.ingredients.find((i) => ["rice_white", "pasta_dry", "potato"].includes(i.canonicalIngredientId))?.canonicalIngredientId,
        vegetables: candidate.ingredients.filter((i) => ["tomato", "zucchini", "paprika", "carrot", "spinach", "onion", "garlic"].includes(i.canonicalIngredientId)).map((i) => i.canonicalIngredientId),
        flavorProfile: inferDietTags(candidate),
        spiceLevel: candidate.spiceLevel,
        method: "stovetop",
        timeMinutes: candidate.totalTimeMinutes,
        calories: Math.round(nutrition.kcal),
        proteinGrams: Math.round(nutrition.proteinG),
      },
      variantType: "standard",
      status: "draft",
      verificationStatus: "verified",
      sourceType: "ai_assisted_reviewed",
      creatorDisplayName: "Cibello AI Smoke",
    });
    seeded++;
  }

  console.error(`[scale-smoke-test] seeded=${seeded}`);
  await closeDatabase();
}

main().catch((err) => { console.error(err); process.exit(1); });
