BEGIN;

CREATE TABLE IF NOT EXISTS locations (
    id SERIAL PRIMARY KEY ,
    name VARCHAR(30) NOT NULL,
    description TEXT NOT NULL,
    parent_id INTEGER,
    CONSTRAINT fk_parent
        FOREIGN KEY (parent_id)
            REFERENCES locations (id)
            ON DELETE SET NULL
);

CREATE TABLE IF NOT EXISTS groups (
    id SERIAL PRIMARY KEY ,
    name VARCHAR(30) NOT NULL,
    description TEXT NOT NULL
);

CREATE TABLE IF NOT EXISTS categories (
    id SERIAL PRIMARY KEY ,
    name VARCHAR(30) NOT NULL,
    description TEXT NOT NULL
);

CREATE TYPE unit AS ENUM (
    'Teaspoon',
    'Tablespoon',
    'Cup',
    'Ounce',
    'Gram',
    'Pound'
);

CREATE TABLE IF NOT EXISTS nutrition (
    id SERIAL PRIMARY KEY ,
    unit unit NOT NULL,
    calories FLOAT NOT NULL,
    fat FLOAT NOT NULL,
    sodium FLOAT NOT NULL,
    protein FLOAT NOT NULL
);

CREATE TYPE vitamin AS ENUM (
    'A',
    'B',
    'C',
    'Iron'
);

CREATE TABLE IF NOT EXISTS vitamins (
    nutrition_id INTEGER NOT NULL,
    vitamin vitamin NOT NULL,
    amount FLOAT NOT NULL,
    CONSTRAINT fk_nutrition
        FOREIGN KEY (nutrition_id)
            REFERENCES nutrition(id)
            ON DELETE CASCADE,
    CONSTRAINT uniq_nutrition_vitamin
        UNIQUE (nutrition_id, vitamin)
);

CREATE TABLE IF NOT EXISTS items (
    id SERIAL PRIMARY KEY ,
    name VARCHAR(30) NOT NULL,
    description TEXT NOT NULL,
    size FLOAT NOT NULL,
    unit unit NOT NULL,
    barcode VARCHAR(100),
    nutrition_id INTEGER,
    CONSTRAINT fk_item_nutrition
        FOREIGN KEY (nutrition_id)
            REFERENCES nutrition (id)
            ON DELETE SET NULL,
    CONSTRAINT uniq_barcode
        UNIQUE (barcode)
);

CREATE TABLE IF NOT EXISTS x_items_locations (
    item_id INTEGER NOT NULL,
    location_id INTEGER NOT NULL,
    count INTEGER NOT NULL,
    CONSTRAINT fk_item
        FOREIGN KEY (item_id)
            REFERENCES items (id)
            ON DELETE CASCADE,
    CONSTRAINT fk_location
        FOREIGN KEY (location_id)
            REFERENCES locations (id)
            ON DELETE CASCADE,
    CONSTRAINT uniq_item_location
        UNIQUE (item_id, location_id)
);

CREATE TABLE IF NOT EXISTS x_items_categories (
    item_id INTEGER NOT NULL,
    category_id INTEGER NOT NULL,
    CONSTRAINT fk_item
        FOREIGN KEY (item_id)
            REFERENCES items (id)
            ON DELETE CASCADE,
    CONSTRAINT fk_category
        FOREIGN KEY (category_id)
            REFERENCES categories (id)
            ON DELETE CASCADE,
    CONSTRAINT uniq_item_category
        UNIQUE (item_id, category_id)
);

CREATE TABLE IF NOT EXISTS x_items_groups (
    item_id INTEGER NOT NULL,
    group_id INTEGER NOT NULL,
    CONSTRAINT fk_item
        FOREIGN KEY (item_id)
            REFERENCES items (id)
            ON DELETE CASCADE,
    CONSTRAINT fk_group
        FOREIGN KEY (group_id)
            REFERENCES groups (id)
            ON DELETE CASCADE,
    CONSTRAINT uniq_item_group
        UNIQUE (item_id, group_id)
);

COMMIT;