import {
  boolean,
  doublePrecision,
  index,
  integer,
  jsonb,
  pgTable,
  text,
  uniqueIndex,
} from "drizzle-orm/pg-core";
import type {
  NutritionDeclaration,
  NutritionProvenance,
  Season,
  StorageLocationType,
} from "@app/shared-types";
import { allergenEnum, unitEnum, updatedAt, createdAt } from "./_shared.js";

/**
 * Kanoniska ingredienser – navet som alla datakällor normaliseras mot (spec §9).
 * Näringsvärden per 100 g/ml med spårbar källa. AI hittar aldrig på värden här:
 * produktion importerar Livsmedelsverkets öppna livsmedelsdatabas via connector.
 */
export const canonicalIngredients = pgTable(
  "canonical_ingredients",
  {
    /** Stabilt slug-id, t.ex. "chicken_breast". */
    id: text("id").primaryKey(),
    nameSv: text("name_sv").notNull(),
    nameEn: text("name_en").notNull(),
    /** Sökhjälp: synonymer och vanliga kvitto-/OCR-varianter. */
    aliases: text("aliases").array().notNull().default([]),
    category: text("category").notNull(),
    defaultUnit: unitEnum("default_unit").notNull(),
    densityGPerMl: doublePrecision("density_g_per_ml"),
    gramsPerPiece: doublePrecision("grams_per_piece"),
    allergens: allergenEnum("allergens").array().notNull().default([]),
    isVegan: boolean("is_vegan").notNull().default(false),
    isVegetarian: boolean("is_vegetarian").notNull().default(false),
    containsGluten: boolean("contains_gluten").notNull().default(false),
    containsLactose: boolean("contains_lactose").notNull().default(false),
    isPork: boolean("is_pork").notNull().default(false),
    isBeef: boolean("is_beef").notNull().default(false),
    isAlcohol: boolean("is_alcohol").notNull().default(false),
    nutritionPer100: jsonb("nutrition_per_100").$type<NutritionDeclaration>().notNull(),
    nutritionProvenance: jsonb("nutrition_provenance").$type<NutritionProvenance>().notNull(),
    peakSeasons: text("peak_seasons").array().$type<Season[]>().notNull().default([]),
    /** Riktvärden i dagar per förvaringsplats – vägledning, aldrig garanti (spec §13). */
    shelfLifeGuidance:
      jsonb("shelf_life_guidance").$type<Partial<Record<StorageLocationType, number>>>(),
    defaultPriceMinorPerKg: integer("default_price_minor_per_kg"),
    createdAt: createdAt(),
    updatedAt: updatedAt(),
  },
  (t) => [index("canonical_ingredients_category_idx").on(t.category)],
);

/** Substitutionsmotor (spec §20): mängdfaktor + påverkan + begränsningar. */
export const substitutions = pgTable(
  "substitutions",
  {
    id: text("id").primaryKey(),
    fromIngredientId: text("from_ingredient_id")
      .notNull()
      .references(() => canonicalIngredients.id),
    toIngredientId: text("to_ingredient_id")
      .notNull()
      .references(() => canonicalIngredients.id),
    ratio: doublePrecision("ratio").notNull().default(1),
    instructionsSv: text("instructions_sv"),
    bestFor: text("best_for").array().notNull().default([]),
    notRecommendedFor: text("not_recommended_for").array().notNull().default([]),
    flavorImpactSv: text("flavor_impact_sv"),
    textureImpactSv: text("texture_impact_sv"),
    priority: integer("priority").notNull().default(0),
  },
  (t) => [
    index("substitutions_from_idx").on(t.fromIngredientId),
    uniqueIndex("substitutions_pair_unique").on(t.fromIngredientId, t.toIngredientId),
  ],
);
