-- +goose Up

-- 1. ingredient_categories: slug-keyed table (the 7 known slugs)
CREATE TABLE ingredient_categories (
    slug       VARCHAR(50) PRIMARY KEY,
    sort_order SMALLINT    NOT NULL DEFAULT 0
);
INSERT INTO ingredient_categories (slug, sort_order) VALUES
    ('dairy', 1), ('meat', 2), ('produce', 3),
    ('bakery', 4), ('frozen', 5), ('beverages', 6), ('other', 7);

-- 2. ingredient_category_translations
CREATE TABLE ingredient_category_translations (
    category_slug VARCHAR(50) NOT NULL REFERENCES ingredient_categories(slug) ON DELETE CASCADE,
    lang          VARCHAR(10) NOT NULL,
    name          TEXT        NOT NULL,
    PRIMARY KEY (category_slug, lang)
);
INSERT INTO ingredient_category_translations (category_slug, lang, name) VALUES
    ('dairy',     'ru', 'Молочные продукты'),
    ('meat',      'ru', 'Мясо и птица'),
    ('produce',   'ru', 'Овощи и фрукты'),
    ('bakery',    'ru', 'Выпечка и хлеб'),
    ('frozen',    'ru', 'Замороженные'),
    ('beverages', 'ru', 'Напитки'),
    ('other',     'ru', 'Прочее');

-- 3. Nullify any unknown category values before adding FK
UPDATE ingredient_mappings
    SET category = NULL
    WHERE category IS NOT NULL
      AND category NOT IN (SELECT slug FROM ingredient_categories);

ALTER TABLE ingredient_mappings
    ADD CONSTRAINT fk_ingredient_category
    FOREIGN KEY (category) REFERENCES ingredient_categories(slug);

-- 4. ingredient_aliases table
CREATE TABLE ingredient_aliases (
    ingredient_id UUID        NOT NULL REFERENCES ingredient_mappings(id) ON DELETE CASCADE,
    lang          VARCHAR(10) NOT NULL,
    alias         TEXT        NOT NULL,
    PRIMARY KEY (ingredient_id, lang, alias)
);
CREATE INDEX idx_ingredient_aliases_lookup ON ingredient_aliases (ingredient_id, lang);
CREATE INDEX idx_ingredient_aliases_trgm   ON ingredient_aliases USING GIN (alias gin_trgm_ops);

-- 5. Migrate English aliases from ingredient_mappings.aliases
INSERT INTO ingredient_aliases (ingredient_id, lang, alias)
SELECT im.id, 'en', a.val
FROM   ingredient_mappings im,
       jsonb_array_elements_text(im.aliases) a(val)
ON CONFLICT DO NOTHING;

-- 6. Migrate per-language aliases from ingredient_translations.aliases
INSERT INTO ingredient_aliases (ingredient_id, lang, alias)
SELECT it.ingredient_id, it.lang, a.val
FROM   ingredient_translations it,
       jsonb_array_elements_text(it.aliases) a(val)
ON CONFLICT DO NOTHING;

-- 7. Drop aliases JSONB columns
DROP INDEX IF EXISTS idx_ingredient_mappings_aliases;
ALTER TABLE ingredient_mappings     DROP COLUMN aliases;
ALTER TABLE ingredient_translations DROP COLUMN aliases;

-- 8. Drop spoonacular_id
ALTER TABLE ingredient_mappings DROP COLUMN spoonacular_id;

-- 9. Unique constraint on canonical_name (replaces spoonacular_id as conflict key)
ALTER TABLE ingredient_mappings
    ADD CONSTRAINT uq_ingredient_canonical_name UNIQUE (canonical_name);

-- +goose Down
ALTER TABLE ingredient_mappings DROP CONSTRAINT IF EXISTS uq_ingredient_canonical_name;
ALTER TABLE ingredient_mappings DROP CONSTRAINT IF EXISTS fk_ingredient_category;
ALTER TABLE ingredient_mappings ADD COLUMN spoonacular_id INTEGER;
ALTER TABLE ingredient_translations ADD COLUMN aliases JSONB NOT NULL DEFAULT '[]'::jsonb;
ALTER TABLE ingredient_mappings     ADD COLUMN aliases JSONB NOT NULL DEFAULT '[]'::jsonb;
-- Restore aliases JSONB from ingredient_aliases (best-effort)
UPDATE ingredient_mappings im
    SET aliases = COALESCE(
        (SELECT json_agg(ia.alias) FROM ingredient_aliases ia
         WHERE ia.ingredient_id = im.id AND ia.lang = 'en'),
        '[]'::json);
DROP TABLE IF EXISTS ingredient_aliases;
DROP TABLE IF EXISTS ingredient_category_translations;
DROP TABLE IF EXISTS ingredient_categories;
CREATE INDEX idx_ingredient_mappings_aliases ON ingredient_mappings USING GIN (aliases);
