"""add billing period

Revision ID: 7875ba8ce0f8
Revises: 529aaa6ceb1c
Create Date: 2025-07-26 10:16:59.486632

"""

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

# revision identifiers, used by Alembic.
revision = "7875ba8ce0f8"
down_revision = "529aaa6ceb1c"
branch_labels = None
depends_on = None


def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "billing_period",
        sa.Column("organization_id", sa.UUID(), nullable=False),
        sa.Column("period_start", sa.DateTime(timezone=True), nullable=False),
        sa.Column("period_end", sa.DateTime(timezone=True), nullable=False),
        sa.Column("plan", sa.String(length=50), nullable=False),
        sa.Column("status", sa.String(length=50), nullable=False),
        sa.Column("stripe_subscription_id", sa.String(), nullable=True),
        sa.Column("stripe_invoice_id", sa.String(), nullable=True),
        sa.Column("amount_cents", sa.Integer(), nullable=True),
        sa.Column("currency", sa.String(length=3), nullable=True),
        sa.Column("paid_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("created_from", sa.String(length=50), nullable=False),
        sa.Column("previous_period_id", sa.UUID(), nullable=True),
        sa.Column("id", sa.UUID(), nullable=False),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.Column("modified_at", sa.DateTime(), nullable=False),
        sa.CheckConstraint("period_end > period_start", name="check_period_end_after_start"),
        sa.ForeignKeyConstraint(["organization_id"], ["organization.id"], ondelete="CASCADE"),
        sa.ForeignKeyConstraint(
            ["previous_period_id"],
            ["billing_period.id"],
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        "ix_billing_period_org_dates",
        "billing_period",
        ["organization_id", "period_start", "period_end"],
        unique=False,
    )
    op.create_index(
        "ix_billing_period_org_status",
        "billing_period",
        ["organization_id", "status"],
        unique=False,
    )
    op.drop_index(op.f("idx_billing_events_org"), table_name="billing_event")
    op.drop_index(op.f("idx_billing_events_type"), table_name="billing_event")
    op.drop_table("billing_event")
    op.add_column(
        "organization_billing",
        sa.Column("pending_plan_change", sa.String(length=50), nullable=True),
    )
    op.add_column(
        "organization_billing",
        sa.Column("pending_plan_change_at", sa.DateTime(timezone=True), nullable=True),
    )
    op.alter_column(
        "organization_billing",
        "billing_plan",
        existing_type=postgresql.ENUM(
            "TRIAL", "DEVELOPER", "STARTUP", "ENTERPRISE", name="billingplan"
        ),
        type_=sa.String(length=50),
        existing_nullable=False,
    )
    op.alter_column(
        "organization_billing",
        "billing_status",
        existing_type=postgresql.ENUM(
            "ACTIVE",
            "PAST_DUE",
            "CANCELED",
            "PAUSED",
            "TRIAL_EXPIRED",
            "GRACE_PERIOD",
            "TRIALING",
            name="billingstatus",
        ),
        type_=sa.String(length=50),
        existing_nullable=False,
    )
    op.alter_column(
        "organization_billing",
        "last_payment_status",
        existing_type=postgresql.ENUM("SUCCEEDED", "FAILED", "PENDING", name="paymentstatus"),
        type_=sa.String(length=50),
        existing_nullable=True,
    )
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.alter_column(
        "organization_billing",
        "last_payment_status",
        existing_type=sa.String(length=50),
        type_=postgresql.ENUM("SUCCEEDED", "FAILED", "PENDING", name="paymentstatus"),
        existing_nullable=True,
    )
    op.alter_column(
        "organization_billing",
        "billing_status",
        existing_type=sa.String(length=50),
        type_=postgresql.ENUM(
            "ACTIVE",
            "PAST_DUE",
            "CANCELED",
            "PAUSED",
            "TRIAL_EXPIRED",
            "GRACE_PERIOD",
            "TRIALING",
            name="billingstatus",
        ),
        existing_nullable=False,
    )
    op.alter_column(
        "organization_billing",
        "billing_plan",
        existing_type=sa.String(length=50),
        type_=postgresql.ENUM("TRIAL", "DEVELOPER", "STARTUP", "ENTERPRISE", name="billingplan"),
        existing_nullable=False,
    )
    op.drop_column("organization_billing", "pending_plan_change_at")
    op.drop_column("organization_billing", "pending_plan_change")

    op.create_table(
        "billing_event",
        sa.Column("id", sa.UUID(), autoincrement=False, nullable=False),
        sa.Column("organization_id", sa.UUID(), autoincrement=False, nullable=False),
        sa.Column("event_type", sa.VARCHAR(length=100), autoincrement=False, nullable=False),
        sa.Column("stripe_event_id", sa.VARCHAR(length=255), autoincrement=False, nullable=True),
        sa.Column(
            "event_data", postgresql.JSON(astext_type=sa.Text()), autoincrement=False, nullable=True
        ),
        sa.Column("created_at", postgresql.TIMESTAMP(), autoincrement=False, nullable=False),
        sa.Column("modified_at", postgresql.TIMESTAMP(), autoincrement=False, nullable=False),
        sa.ForeignKeyConstraint(
            ["organization_id"],
            ["organization.id"],
            name=op.f("billing_event_organization_id_fkey"),
            ondelete="CASCADE",
        ),
        sa.PrimaryKeyConstraint("id", name=op.f("billing_event_pkey")),
        sa.UniqueConstraint(
            "stripe_event_id",
            name=op.f("billing_event_stripe_event_id_key"),
            postgresql_include=[],
            postgresql_nulls_not_distinct=False,
        ),
    )
    op.create_index(op.f("idx_billing_events_type"), "billing_event", ["event_type"], unique=False)
    op.create_index(
        op.f("idx_billing_events_org"), "billing_event", ["organization_id"], unique=False
    )
    op.drop_index("ix_billing_period_org_status", table_name="billing_period")
    op.drop_index("ix_billing_period_org_dates", table_name="billing_period")
    op.drop_table("billing_period")
    # ### end Alembic commands ###
