"""Add product_render_positions table and render_position_id on order_lines.

Revision ID: 028
Revises: 027
Create Date: 2026-03-04
"""
from alembic import op
import sqlalchemy as sa

revision = "028"
down_revision = "027"
branch_labels = None
depends_on = None

NIL_UUID = "00000000-0000-0000-0000-000000000000"


def upgrade() -> None:
    # ── New table: product_render_positions ──────────────────────────────────
    op.execute("""
        CREATE TABLE product_render_positions (
            id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
            product_id UUID NOT NULL REFERENCES products(id) ON DELETE CASCADE,
            name VARCHAR(200) NOT NULL,
            rotation_x DOUBLE PRECISION NOT NULL DEFAULT 0,
            rotation_y DOUBLE PRECISION NOT NULL DEFAULT 0,
            rotation_z DOUBLE PRECISION NOT NULL DEFAULT 0,
            is_default BOOLEAN NOT NULL DEFAULT false,
            sort_order INTEGER NOT NULL DEFAULT 0,
            created_at TIMESTAMP NOT NULL DEFAULT NOW(),
            updated_at TIMESTAMP NOT NULL DEFAULT NOW()
        )
    """)
    op.execute(
        "CREATE UNIQUE INDEX uq_render_positions_product_name "
        "ON product_render_positions (product_id, lower(name))"
    )
    op.execute("CREATE INDEX ix_render_positions_product_id ON product_render_positions (product_id)")

    # ── Add render_position_id to order_lines ────────────────────────────────
    op.execute(
        "ALTER TABLE order_lines ADD COLUMN render_position_id UUID "
        "REFERENCES product_render_positions(id) ON DELETE SET NULL"
    )

    # ── Update unique indexes to include position ─────────────────────────────
    op.execute("DROP INDEX IF EXISTS uq_order_lines_tracking")
    op.execute("DROP INDEX IF EXISTS uq_order_lines_render")

    op.execute(
        f"CREATE UNIQUE INDEX uq_order_lines_tracking "
        f"ON order_lines (order_id, product_id, COALESCE(render_position_id, '{NIL_UUID}'::uuid)) "
        f"WHERE output_type_id IS NULL"
    )
    op.execute(
        f"CREATE UNIQUE INDEX uq_order_lines_render "
        f"ON order_lines (order_id, product_id, output_type_id, "
        f"COALESCE(render_position_id, '{NIL_UUID}'::uuid)) "
        f"WHERE output_type_id IS NOT NULL"
    )


def downgrade() -> None:
    # Restore original unique indexes (without position)
    op.execute("DROP INDEX IF EXISTS uq_order_lines_tracking")
    op.execute("DROP INDEX IF EXISTS uq_order_lines_render")

    op.execute("ALTER TABLE order_lines DROP COLUMN IF EXISTS render_position_id")

    op.execute(
        "CREATE UNIQUE INDEX uq_order_lines_tracking "
        "ON order_lines (order_id, product_id) "
        "WHERE output_type_id IS NULL"
    )
    op.execute(
        "CREATE UNIQUE INDEX uq_order_lines_render "
        "ON order_lines (order_id, product_id, output_type_id) "
        "WHERE output_type_id IS NOT NULL"
    )

    op.execute("DROP TABLE IF EXISTS product_render_positions CASCADE")
