"""Link ExternalOrganization to Organization

Revision ID: 4fb5c2b88e8c
Revises: 7b35e72d3a15
Create Date: 2024-07-16 11:04:12.912639

"""

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

# Polar Custom Imports

# revision identifiers, used by Alembic.
revision = "4fb5c2b88e8c"
down_revision = "7b35e72d3a15"
branch_labels: tuple[str] | None = None
depends_on: tuple[str] | None = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        "external_organizations", sa.Column("organization_id", sa.UUID(), nullable=True)
    )
    op.create_foreign_key(
        op.f("external_organizations_organization_id_fkey"),
        "external_organizations",
        "organizations",
        ["organization_id"],
        ["id"],
        ondelete="set null",
    )

    # Link ExternalOrganization to Organization
    op.execute(
        """
        UPDATE external_organizations
        SET organization_id = organizations.id
        FROM organizations
        WHERE external_organizations.external_id = organizations.external_id
        """
    )

    op.alter_column(
        "organizations",
        "name",
        new_column_name="slug",
        existing_type=postgresql.CITEXT(),
        existing_nullable=False,
    )

    op.drop_constraint("organizations_external_id_key", "organizations", type_="unique")
    op.drop_constraint(
        "organizations_installation_id_key", "organizations", type_="unique"
    )
    op.drop_constraint("organizations_name_key", "organizations", type_="unique")
    op.create_unique_constraint(
        op.f("organizations_slug_key"), "organizations", ["slug"]
    )
    op.drop_column("organizations", "installation_permissions")
    op.drop_column("organizations", "installation_suspender")
    op.drop_column("organizations", "installation_created_at")
    op.drop_column("organizations", "is_personal")
    op.drop_column("organizations", "installation_id")
    op.drop_column("organizations", "external_id")
    op.drop_column("organizations", "platform")
    op.drop_column("organizations", "installation_updated_at")
    op.drop_column("organizations", "installation_suspended_at")
    op.drop_column("organizations", "installation_suspended_by")
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        "organizations",
        sa.Column(
            "installation_suspended_by",
            sa.INTEGER(),
            autoincrement=False,
            nullable=True,
        ),
    )
    op.add_column(
        "organizations",
        sa.Column(
            "installation_suspended_at",
            postgresql.TIMESTAMP(timezone=True),
            autoincrement=False,
            nullable=True,
        ),
    )
    op.add_column(
        "organizations",
        sa.Column(
            "installation_updated_at",
            postgresql.TIMESTAMP(timezone=True),
            autoincrement=False,
            nullable=True,
        ),
    )
    op.add_column(
        "organizations",
        sa.Column("platform", sa.VARCHAR(), autoincrement=False, nullable=True),
    )
    op.add_column(
        "organizations",
        sa.Column("external_id", sa.BIGINT(), autoincrement=False, nullable=True),
    )
    op.add_column(
        "organizations",
        sa.Column("installation_id", sa.INTEGER(), autoincrement=False, nullable=True),
    )
    op.add_column(
        "organizations",
        sa.Column("is_personal", sa.BOOLEAN(), autoincrement=False, nullable=True),
    )
    op.add_column(
        "organizations",
        sa.Column(
            "installation_created_at",
            postgresql.TIMESTAMP(timezone=True),
            autoincrement=False,
            nullable=True,
        ),
    )
    op.add_column(
        "organizations",
        sa.Column(
            "installation_suspender", sa.UUID(), autoincrement=False, nullable=True
        ),
    )
    op.add_column(
        "organizations",
        sa.Column(
            "installation_permissions",
            postgresql.JSONB(astext_type=sa.Text()),
            autoincrement=False,
            nullable=True,
        ),
    )

    op.alter_column(
        "organizations",
        "slug",
        new_column_name="name",
        existing_type=postgresql.CITEXT(),
        existing_nullable=False,
    )

    op.drop_constraint(op.f("organizations_slug_key"), "organizations", type_="unique")
    op.create_unique_constraint("organizations_name_key", "organizations", ["name"])
    op.create_unique_constraint(
        "organizations_installation_id_key", "organizations", ["installation_id"]
    )
    op.create_unique_constraint(
        "organizations_external_id_key", "organizations", ["external_id"]
    )

    # Fill created fields from ExternalOrganization
    op.execute(
        """
        UPDATE organizations
        SET platform = external_organizations.platform,
            external_id = external_organizations.external_id,
            installation_id = external_organizations.installation_id,
            is_personal = external_organizations.is_personal,
            installation_created_at = external_organizations.installation_created_at,
            installation_updated_at = external_organizations.installation_updated_at,
            installation_suspended_at = external_organizations.installation_suspended_at,
            installation_suspended_by = external_organizations.installation_suspended_by,
            installation_suspender = external_organizations.installation_suspender,
            installation_permissions = external_organizations.installation_permissions
        FROM external_organizations
        WHERE external_organizations.organization_id = organizations.id
        """
    )

    op.alter_column(
        "organizations",
        "platform",
        existing_type=sa.VARCHAR(),
        nullable=False,
    )
    op.alter_column(
        "organizations",
        "external_id",
        existing_type=sa.BIGINT(),
        nullable=False,
    )
    op.alter_column(
        "organizations",
        "is_personal",
        existing_type=sa.BOOLEAN(),
        nullable=False,
    )

    op.drop_constraint(
        op.f("external_organizations_organization_id_fkey"),
        "external_organizations",
        type_="foreignkey",
    )
    op.drop_column("external_organizations", "organization_id")
    # ### end Alembic commands ###
