"""Multiple products on Checkout & Checkout Links

Revision ID: 69d1834e6285
Revises: 44f8c56e3ddc
Create Date: 2025-02-17 09:15:30.950787

"""

import sqlalchemy as sa
from alembic import op

# Polar Custom Imports

# revision identifiers, used by Alembic.
revision = "69d1834e6285"
down_revision = "44f8c56e3ddc"
branch_labels: tuple[str] | None = None
depends_on: tuple[str] | None = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###

    # Checkout
    op.create_table(
        "checkout_products",
        sa.Column("checkout_id", sa.Uuid(), nullable=False),
        sa.Column("product_id", sa.Uuid(), nullable=False),
        sa.Column("order", sa.Integer(), nullable=False),
        sa.Column("id", sa.Uuid(), nullable=False),
        sa.Column("created_at", sa.TIMESTAMP(timezone=True), nullable=False),
        sa.Column("modified_at", sa.TIMESTAMP(timezone=True), nullable=True),
        sa.Column("deleted_at", sa.TIMESTAMP(timezone=True), nullable=True),
        sa.ForeignKeyConstraint(
            ["checkout_id"],
            ["checkouts.id"],
            name=op.f("checkout_products_checkout_id_fkey"),
            ondelete="cascade",
        ),
        sa.ForeignKeyConstraint(
            ["product_id"],
            ["products.id"],
            name=op.f("checkout_products_product_id_fkey"),
            ondelete="cascade",
        ),
        sa.PrimaryKeyConstraint("id", name=op.f("checkout_products_pkey")),
        sa.UniqueConstraint(
            "checkout_id", "order", name=op.f("checkout_products_checkout_id_order_key")
        ),
        sa.UniqueConstraint(
            "checkout_id",
            "product_id",
            name=op.f("checkout_products_checkout_id_product_id_key"),
        ),
    )
    op.create_index(
        op.f("ix_checkout_products_created_at"),
        "checkout_products",
        ["created_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_checkout_products_deleted_at"),
        "checkout_products",
        ["deleted_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_checkout_products_modified_at"),
        "checkout_products",
        ["modified_at"],
        unique=False,
    )

    op.execute("""
        INSERT INTO checkout_products (id, checkout_id, product_id, "order", created_at)
        SELECT uuid_generate_v4(), id, product_id, 0, created_at
        FROM checkouts
    """)

    # Checkout Links
    op.create_table(
        "checkout_link_products",
        sa.Column("checkout_link_id", sa.Uuid(), nullable=False),
        sa.Column("product_id", sa.Uuid(), nullable=False),
        sa.Column("order", sa.Integer(), nullable=False),
        sa.Column("id", sa.Uuid(), nullable=False),
        sa.Column("created_at", sa.TIMESTAMP(timezone=True), nullable=False),
        sa.Column("modified_at", sa.TIMESTAMP(timezone=True), nullable=True),
        sa.Column("deleted_at", sa.TIMESTAMP(timezone=True), nullable=True),
        sa.ForeignKeyConstraint(
            ["checkout_link_id"],
            ["checkout_links.id"],
            name=op.f("checkout_link_products_checkout_link_id_fkey"),
            ondelete="cascade",
        ),
        sa.ForeignKeyConstraint(
            ["product_id"],
            ["products.id"],
            name=op.f("checkout_link_products_product_id_fkey"),
            ondelete="cascade",
        ),
        sa.PrimaryKeyConstraint("id", name=op.f("checkout_link_products_pkey")),
        sa.UniqueConstraint(
            "checkout_link_id",
            "order",
            name=op.f("checkout_link_products_checkout_link_id_order_key"),
        ),
        sa.UniqueConstraint(
            "checkout_link_id",
            "product_id",
            name=op.f("checkout_link_products_checkout_link_id_product_id_key"),
        ),
    )
    op.create_index(
        op.f("ix_checkout_link_products_created_at"),
        "checkout_link_products",
        ["created_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_checkout_link_products_deleted_at"),
        "checkout_link_products",
        ["deleted_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_checkout_link_products_modified_at"),
        "checkout_link_products",
        ["modified_at"],
        unique=False,
    )

    op.add_column(
        "checkout_links", sa.Column("organization_id", sa.Uuid(), nullable=True)
    )
    op.execute("""
        UPDATE checkout_links
        SET organization_id = products.organization_id
        FROM products
        WHERE checkout_links.product_id = products.id
    """)
    op.alter_column("checkout_links", "organization_id", nullable=False)
    op.create_foreign_key(
        op.f("checkout_links_organization_id_fkey"),
        "checkout_links",
        "organizations",
        ["organization_id"],
        ["id"],
        ondelete="cascade",
    )

    op.execute("""
        INSERT INTO checkout_link_products (id, checkout_link_id, product_id, "order", created_at)
        SELECT uuid_generate_v4(), id, product_id, 0, created_at
        FROM checkout_links
    """)

    op.drop_constraint(
        "checkout_links_product_price_id_fkey", "checkout_links", type_="foreignkey"
    )
    op.drop_constraint(
        "checkout_links_product_id_fkey", "checkout_links", type_="foreignkey"
    )
    op.drop_column("checkout_links", "product_price_id")
    op.drop_column("checkout_links", "product_id")
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        "checkout_links",
        sa.Column("product_id", sa.UUID(), autoincrement=False, nullable=True),
    )

    op.execute("""
        UPDATE checkout_links
        SET product_id = checkout_link_products.product_id
        FROM checkout_link_products
        WHERE checkout_links.id = checkout_link_products.checkout_link_id
    """)

    op.add_column(
        "checkout_links",
        sa.Column("product_price_id", sa.UUID(), autoincrement=False, nullable=True),
    )

    op.drop_constraint(
        op.f("checkout_links_organization_id_fkey"),
        "checkout_links",
        type_="foreignkey",
    )
    op.create_foreign_key(
        "checkout_links_product_id_fkey",
        "checkout_links",
        "products",
        ["product_id"],
        ["id"],
        ondelete="CASCADE",
    )
    op.create_foreign_key(
        "checkout_links_product_price_id_fkey",
        "checkout_links",
        "product_prices",
        ["product_price_id"],
        ["id"],
        ondelete="SET NULL",
    )
    op.drop_column("checkout_links", "organization_id")
    op.drop_index(
        op.f("ix_checkout_link_products_modified_at"),
        table_name="checkout_link_products",
    )
    op.drop_index(
        op.f("ix_checkout_link_products_deleted_at"),
        table_name="checkout_link_products",
    )
    op.drop_index(
        op.f("ix_checkout_link_products_created_at"),
        table_name="checkout_link_products",
    )
    op.drop_table("checkout_link_products")
    op.drop_index(
        op.f("ix_checkout_products_modified_at"), table_name="checkout_products"
    )
    op.drop_index(
        op.f("ix_checkout_products_deleted_at"), table_name="checkout_products"
    )
    op.drop_index(
        op.f("ix_checkout_products_created_at"), table_name="checkout_products"
    )
    op.drop_table("checkout_products")
    # ### end Alembic commands ###
