PRAGMA foreign_keys = ON;

CREATE TABLE units (
  id TEXT PRIMARY KEY, name TEXT NOT NULL, symbol TEXT NOT NULL,
  dimension TEXT NOT NULL, system TEXT NOT NULL,
  base_unit_id TEXT REFERENCES units(id), factor REAL, offset REAL
);

CREATE TABLE ingredients (
  id TEXT PRIMARY KEY, schema_version INTEGER NOT NULL, name TEXT NOT NULL,
  status TEXT NOT NULL, categories_json TEXT NOT NULL DEFAULT '[]',
  tags_json TEXT NOT NULL DEFAULT '[]', description TEXT,
  source_json TEXT NOT NULL DEFAULT '{}', deleted_at TEXT
);

CREATE TABLE ingredient_aliases (
  ingredient_id TEXT NOT NULL REFERENCES ingredients(id) ON DELETE CASCADE,
  name TEXT NOT NULL, kind TEXT, PRIMARY KEY (ingredient_id, name)
);

CREATE TABLE equipment (
  id TEXT PRIMARY KEY, name TEXT NOT NULL, category TEXT, notes TEXT
);

CREATE TABLE prep_actions (
  id TEXT PRIMARY KEY, name TEXT NOT NULL, action_type TEXT NOT NULL,
  default_yield_factor REAL CHECK(default_yield_factor > 0), notes TEXT
);

CREATE TABLE recipes (
  id TEXT PRIMARY KEY, schema_version INTEGER NOT NULL,
  save_version INTEGER NOT NULL DEFAULT 1, title TEXT NOT NULL, summary TEXT,
  categories_json TEXT NOT NULL DEFAULT '[]', tags_json TEXT NOT NULL DEFAULT '[]',
  yield_quantity REAL NOT NULL, yield_unit_id TEXT NOT NULL REFERENCES units(id),
  yield_servings REAL, yield_basis TEXT, scaling_mode TEXT, scaling_basis_id TEXT,
  scaling_basis_quantity REAL, scaling_basis_unit_id TEXT REFERENCES units(id),
  notes_json TEXT NOT NULL DEFAULT '[]', source_json TEXT NOT NULL DEFAULT '{}',
  auto_yield INTEGER NOT NULL DEFAULT 0, station TEXT, deleted_at TEXT,
  cover_media_url TEXT
);

CREATE TABLE recipe_components (
  recipe_id TEXT NOT NULL REFERENCES recipes(id) ON DELETE CASCADE,
  id TEXT NOT NULL, position INTEGER NOT NULL, name TEXT NOT NULL,
  notes_json TEXT NOT NULL DEFAULT '[]', PRIMARY KEY (recipe_id, id)
);

CREATE TABLE recipe_items (
  recipe_id TEXT NOT NULL, component_id TEXT NOT NULL, id TEXT NOT NULL,
  position INTEGER NOT NULL, ingredient_id TEXT REFERENCES ingredients(id),
  subrecipe_id TEXT REFERENCES recipes(id), quantity REAL NOT NULL,
  unit_id TEXT NOT NULL REFERENCES units(id), percentage REAL,
  basis_member INTEGER NOT NULL DEFAULT 0, optional INTEGER NOT NULL DEFAULT 0,
  notes TEXT, nutrition_retention_factor REAL NOT NULL DEFAULT 1
    CHECK(nutrition_retention_factor >= 0 AND nutrition_retention_factor <= 1),
  PRIMARY KEY (recipe_id, id),
  FOREIGN KEY (recipe_id, component_id)
    REFERENCES recipe_components(recipe_id, id) ON DELETE CASCADE,
  CHECK ((ingredient_id IS NOT NULL) <> (subrecipe_id IS NOT NULL))
);

CREATE TABLE ingredient_prep_actions (
  ingredient_id TEXT NOT NULL REFERENCES ingredients(id) ON DELETE CASCADE,
  action_id TEXT NOT NULL REFERENCES prep_actions(id),
  yield_factor REAL NOT NULL CHECK(yield_factor > 0), notes TEXT,
  PRIMARY KEY (ingredient_id, action_id)
);

CREATE TABLE item_prep_actions (
  recipe_id TEXT NOT NULL, item_id TEXT NOT NULL, position INTEGER NOT NULL,
  action_id TEXT NOT NULL REFERENCES prep_actions(id),
  yield_factor REAL CHECK(yield_factor > 0), notes TEXT,
  PRIMARY KEY (recipe_id, item_id, position),
  FOREIGN KEY (recipe_id, item_id) REFERENCES recipe_items(recipe_id, id) ON DELETE CASCADE
);

CREATE TABLE recipe_steps (
  recipe_id TEXT NOT NULL REFERENCES recipes(id) ON DELETE CASCADE,
  id TEXT NOT NULL, position INTEGER NOT NULL, instruction TEXT NOT NULL,
  critical_control_point INTEGER NOT NULL DEFAULT 0,
  PRIMARY KEY (recipe_id, id), UNIQUE (recipe_id, position)
);

CREATE TABLE recipe_equipment (
  recipe_id TEXT NOT NULL REFERENCES recipes(id) ON DELETE CASCADE,
  equipment_id TEXT NOT NULL REFERENCES equipment(id),
  PRIMARY KEY (recipe_id, equipment_id)
);

CREATE TABLE step_equipment (
  recipe_id TEXT NOT NULL, step_id TEXT NOT NULL,
  equipment_id TEXT NOT NULL REFERENCES equipment(id),
  PRIMARY KEY (recipe_id, step_id, equipment_id),
  FOREIGN KEY (recipe_id, step_id) REFERENCES recipe_steps(recipe_id, id) ON DELETE CASCADE
);

CREATE TABLE ingredient_measure_conversions (
  ingredient_id TEXT NOT NULL REFERENCES ingredients(id) ON DELETE CASCADE,
  id TEXT NOT NULL, from_quantity REAL NOT NULL,
  from_unit_id TEXT NOT NULL REFERENCES units(id), to_quantity REAL NOT NULL,
  to_unit_id TEXT NOT NULL REFERENCES units(id), state TEXT,
  source_json TEXT NOT NULL, PRIMARY KEY (ingredient_id, id)
);

CREATE TABLE ingredient_density_measurements (
  ingredient_id TEXT NOT NULL REFERENCES ingredients(id) ON DELETE CASCADE,
  id TEXT NOT NULL, mass_quantity REAL NOT NULL,
  mass_unit_id TEXT NOT NULL REFERENCES units(id), volume_quantity REAL NOT NULL,
  volume_unit_id TEXT NOT NULL REFERENCES units(id), temperature_c REAL,
  state TEXT, source_json TEXT NOT NULL, PRIMARY KEY (ingredient_id, id)
);

CREATE TABLE recipe_measure_conversions (
  recipe_id TEXT NOT NULL REFERENCES recipes(id) ON DELETE CASCADE,
  id TEXT NOT NULL, from_quantity REAL NOT NULL CHECK(from_quantity > 0),
  from_unit_id TEXT NOT NULL REFERENCES units(id),
  to_quantity REAL NOT NULL CHECK(to_quantity > 0),
  to_unit_id TEXT NOT NULL REFERENCES units(id), notes TEXT,
  source_json TEXT NOT NULL DEFAULT '{}', PRIMARY KEY (recipe_id, id)
);

CREATE TABLE purchase_items (
  id TEXT PRIMARY KEY, ingredient_id TEXT NOT NULL REFERENCES ingredients(id),
  name TEXT NOT NULL, brand TEXT, supplier_id TEXT, supplier_sku TEXT,
  status TEXT NOT NULL, package_quantity REAL NOT NULL,
  package_unit_id TEXT NOT NULL REFERENCES units(id),
  units_per_case INTEGER NOT NULL DEFAULT 1,
  usable_yield_factor REAL NOT NULL DEFAULT 1
);

CREATE TABLE price_observations (
  purchase_item_id TEXT NOT NULL REFERENCES purchase_items(id) ON DELETE CASCADE,
  effective_at TEXT NOT NULL, currency TEXT NOT NULL, amount REAL NOT NULL,
  source_json TEXT NOT NULL,
  PRIMARY KEY (purchase_item_id, effective_at, currency)
);

CREATE TABLE source_mappings (
  id TEXT PRIMARY KEY, subject_type TEXT NOT NULL, subject_id TEXT NOT NULL,
  mapping_type TEXT NOT NULL, status TEXT NOT NULL,
  source_json TEXT NOT NULL, nutrition_json TEXT
);

CREATE TABLE collections (
  id TEXT PRIMARY KEY, name TEXT NOT NULL, description TEXT,
  source_json TEXT NOT NULL, deleted_at TEXT
);

CREATE TABLE collection_recipes (
  collection_id TEXT NOT NULL REFERENCES collections(id) ON DELETE CASCADE,
  recipe_id TEXT NOT NULL REFERENCES recipes(id), position INTEGER NOT NULL,
  PRIMARY KEY (collection_id, recipe_id)
);

CREATE TABLE recipe_media (
  recipe_id TEXT NOT NULL REFERENCES recipes(id) ON DELETE CASCADE,
  id TEXT NOT NULL, step_id TEXT, media_type TEXT NOT NULL
    CHECK(media_type IN ('image', 'video')),
  url TEXT NOT NULL, caption TEXT, position INTEGER NOT NULL,
  PRIMARY KEY (recipe_id, id),
  FOREIGN KEY (recipe_id, step_id) REFERENCES recipe_steps(recipe_id, id) ON DELETE CASCADE
);

CREATE INDEX recipe_items_ingredient_idx ON recipe_items(ingredient_id);
CREATE INDEX recipe_items_subrecipe_idx ON recipe_items(subrecipe_id);
CREATE INDEX purchase_items_ingredient_idx ON purchase_items(ingredient_id);
CREATE INDEX source_mappings_subject_idx ON source_mappings(subject_type, subject_id);
CREATE INDEX recipe_media_recipe_idx ON recipe_media(recipe_id, position);
