"""add product attributes, nutrition, allergens and extra product columns

Revision ID: 20251107_153000_product_attributes_nutrition
Revises: 20251107_123000_widen_alembic_version
Create Date: 2025-11-07T15:30:00.000000
"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = "20251107_153000_product_attributes_nutrition"
down_revision = "20251107_123000_widen_alembic_version"
branch_labels = None
depends_on = None


def upgrade() -> None:
    # --- products extra columns ---
    with op.batch_alter_table("products") as batch_op:
        batch_op.add_column(sa.Column("ean", sa.String(length=64), nullable=True))
        batch_op.add_column(sa.Column("sku", sa.String(length=128), nullable=True))
        batch_op.add_column(sa.Column("unit_size", sa.String(length=128), nullable=True))
        batch_op.add_column(sa.Column("pack_size", sa.String(length=128), nullable=True))
        batch_op.create_index("ix_products_ean", ["ean"], unique=False)
        batch_op.create_index("ix_products_sku", ["sku"], unique=False)

    # --- attributes: arbitrary key/value facts (e.g., Brand, Origin, etc.) ---
    op.create_table(
        "product_attributes",
        sa.Column("id", sa.Integer(), primary_key=True),
        sa.Column("product_id", sa.Integer(), sa.ForeignKey("products.id", ondelete="CASCADE"), nullable=False),
        sa.Column("key", sa.String(length=255), nullable=False),
        sa.Column("value", sa.Text(), nullable=True),
    )
    op.create_index("ix_product_attributes_product_id", "product_attributes", ["product_id"], unique=False)
    op.create_index("ix_product_attributes_key", "product_attributes", ["key"], unique=False)
    op.create_unique_constraint(
        "uq_product_attributes_product_key", "product_attributes", ["product_id", "key"]
    )

    # --- nutrition: key/value[+unit] rows (e.g., Energy, Fat, Protein) ---
    op.create_table(
        "product_nutrition",
        sa.Column("id", sa.Integer(), primary_key=True),
        sa.Column("product_id", sa.Integer(), sa.ForeignKey("products.id", ondelete="CASCADE"), nullable=False),
        sa.Column("key", sa.String(length=255), nullable=False),
        sa.Column("value", sa.String(length=255), nullable=True),
        sa.Column("unit", sa.String(length=64), nullable=True),
    )
    op.create_index("ix_product_nutrition_product_id", "product_nutrition", ["product_id"], unique=False)
    op.create_index("ix_product_nutrition_key", "product_nutrition", ["key"], unique=False)
    op.create_unique_constraint(
        "uq_product_nutrition_product_key", "product_nutrition", ["product_id", "key"]
    )

    # --- allergens: one row per allergen mention (name + contains boolean) ---
    op.create_table(
        "product_allergens",
        sa.Column("id", sa.Integer(), primary_key=True),
        sa.Column("product_id", sa.Integer(), sa.ForeignKey("products.id", ondelete="CASCADE"), nullable=False),
        sa.Column("name", sa.String(length=255), nullable=False),
        sa.Column("contains", sa.Boolean(), nullable=False, server_default=sa.false()),
    )
    op.create_index("ix_product_allergens_product_id", "product_allergens", ["product_id"], unique=False)
    op.create_index("ix_product_allergens_name", "product_allergens", ["name"], unique=False)
    op.create_unique_constraint(
        "uq_product_allergens_product_name", "product_allergens", ["product_id", "name"]
    )


def downgrade() -> None:
    op.drop_constraint("uq_product_allergens_product_name", "product_allergens", type_="unique")
    op.drop_index("ix_product_allergens_name", table_name="product_allergens")
    op.drop_index("ix_product_allergens_product_id", table_name="product_allergens")
    op.drop_table("product_allergens")

    op.drop_constraint("uq_product_nutrition_product_key", "product_nutrition", type_="unique")
    op.drop_index("ix_product_nutrition_key", table_name="product_nutrition")
    op.drop_index("ix_product_nutrition_product_id", table_name="product_nutrition")
    op.drop_table("product_nutrition")

    op.drop_constraint("uq_product_attributes_product_key", "product_attributes", type_="unique")
    op.drop_index("ix_product_attributes_key", table_name="product_attributes")
    op.drop_index("ix_product_attributes_product_id", table_name="product_attributes")
    op.drop_table("product_attributes")

    with op.batch_alter_table("products") as batch_op:
        batch_op.drop_index("ix_products_sku")
        batch_op.drop_index("ix_products_ean")
        batch_op.drop_column("pack_size")
        batch_op.drop_column("unit_size")
        batch_op.drop_column("sku")
        batch_op.drop_column("ean")
