"""Cloud credit wallet, conversion rates, wallet alerts, codegen Pro 900.

Revision ID: 097
Revises: 096
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

revision = "097"
down_revision = "096"
branch_labels = None
depends_on = None


def upgrade() -> None:
    op.execute("""
        UPDATE subscription_plans
        SET limits = COALESCE(limits, '{}'::jsonb) || '{"included_ai_units": 900}'::jsonb
        WHERE LOWER(slug) = 'pro'
    """)

    op.create_table(
        "cloud_credit_packages",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column("slug", sa.String(50), nullable=False, unique=True),
        sa.Column("name", sa.String(100), nullable=False),
        sa.Column("description", sa.Text(), nullable=True),
        sa.Column("credits", sa.Integer(), nullable=False),
        sa.Column("price_minor", sa.BigInteger(), nullable=False),
        sa.Column("currency", sa.String(10), nullable=False, server_default="usd"),
        sa.Column("stripe_product_id", sa.String(100), nullable=True),
        sa.Column("stripe_price_id", sa.String(100), nullable=True),
        sa.Column("is_active", sa.Boolean(), nullable=False, server_default="true"),
        sa.Column("sort_order", sa.Integer(), nullable=False, server_default="0"),
        sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
        sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
    )
    op.create_table(
        "cloud_credit_purchases",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column(
            "workspace_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("workspaces.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("stripe_customer_id", sa.String(100), nullable=False),
        sa.Column("stripe_checkout_session_id", sa.String(100), nullable=True),
        sa.Column("stripe_payment_intent_id", sa.String(100), nullable=True),
        sa.Column("package_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("cloud_credit_packages.id"), nullable=True),
        sa.Column("package_slug", sa.String(50), nullable=False),
        sa.Column("credits_purchased", sa.Integer(), nullable=False),
        sa.Column("millicredits_purchased", sa.Integer(), nullable=False),
        sa.Column("amount_minor", sa.BigInteger(), nullable=False),
        sa.Column("currency", sa.String(10), nullable=False, server_default="usd"),
        sa.Column("status", sa.String(30), nullable=False),
        sa.Column("paid_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
        sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
        sa.UniqueConstraint("stripe_checkout_session_id", name="uq_cloud_credit_purchase_session"),
    )
    op.create_table(
        "cloud_credit_ledger",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column(
            "workspace_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("workspaces.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("entry_type", sa.String(30), nullable=False),
        sa.Column("millicredits_delta", sa.Integer(), nullable=False),
        sa.Column("balance_after", sa.Integer(), nullable=True),
        sa.Column("source_type", sa.String(50), nullable=True),
        sa.Column("source_id", sa.String(100), nullable=True),
        sa.Column("purchase_id", postgresql.UUID(as_uuid=True), sa.ForeignKey("cloud_credit_purchases.id"), nullable=True),
        sa.Column("project_id", postgresql.UUID(as_uuid=True), nullable=True),
        sa.Column("description", sa.Text(), nullable=True),
        sa.Column("metadata_json", postgresql.JSONB(), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
    )
    op.create_index("idx_cloud_credit_ledger_workspace", "cloud_credit_ledger", ["workspace_id", "created_at"])
    op.create_index(
        "idx_cloud_credit_ledger_source",
        "cloud_credit_ledger",
        ["workspace_id", "source_type", "source_id", "created_at"],
    )

    op.create_table(
        "cloud_usage_conversion_rates",
        sa.Column("metric_key", sa.String(50), primary_key=True),
        sa.Column("credits_per_unit", sa.Numeric(20, 10), nullable=False, server_default="0"),
        sa.Column("is_active", sa.Boolean(), nullable=False, server_default="true"),
        sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
    )
    op.execute("""
        INSERT INTO cloud_usage_conversion_rates (metric_key, credits_per_unit, is_active)
        VALUES
          ('hosted_app_requests', 0.0001, true),
          ('hosted_app_egress_bytes', 0.000000001, true),
          ('cpu_minutes', 0.1, true),
          ('db_reads', 0.00001, true),
          ('db_writes', 0.0001, true),
          ('storage_gb', 1, true),
          ('job_executions', 1, true),
          ('ai_embed_tokens', 0.00001, true),
          ('ai_completion_tokens', 0.00003, true),
          ('ai_searches', 0.001, true),
          ('ext_queries', 0.001, true)
    """)

    op.create_table(
        "workspace_cloud_credit_policies",
        sa.Column(
            "workspace_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("workspaces.id", ondelete="CASCADE"),
            primary_key=True,
        ),
        sa.Column("enforcement_enabled", sa.Boolean(), nullable=False, server_default="false"),
        sa.Column("cap_credits", sa.Integer(), nullable=True),
        sa.Column("public_blocked_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
        sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
    )

    op.create_table(
        "workspace_wallet_alerts",
        sa.Column("id", postgresql.UUID(as_uuid=True), primary_key=True),
        sa.Column(
            "workspace_id",
            postgresql.UUID(as_uuid=True),
            sa.ForeignKey("workspaces.id", ondelete="CASCADE"),
            nullable=False,
        ),
        sa.Column("wallet_type", sa.String(20), nullable=False),
        sa.Column("period_start", sa.Date(), nullable=False),
        sa.Column("notified_80pct_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("notified_100pct_at", sa.DateTime(timezone=True), nullable=True),
        sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
        sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()")),
        sa.UniqueConstraint("workspace_id", "wallet_type", "period_start", name="uq_workspace_wallet_alert_period"),
    )

    op.execute("""
        INSERT INTO cloud_credit_packages (id, slug, name, description, credits, price_minor, currency, is_active, sort_order)
        VALUES
          ('b1111111-1111-4111-8111-111111111111', 'cloud_1k', '1,000 Cloud credits',
           'Pay-as-you-go Cloud credits for hosted traffic and P2HS Cloud usage. Separate from codegen.', 1000, 900, 'usd', true, 10),
          ('b2222222-2222-4222-8222-222222222222', 'cloud_5k', '5,000 Cloud credits',
           'Pay-as-you-go Cloud credits for hosted traffic and P2HS Cloud usage. Separate from codegen.', 5000, 3500, 'usd', true, 20),
          ('b3333333-3333-4333-8333-333333333333', 'cloud_25k', '25,000 Cloud credits',
           'Pay-as-you-go Cloud credits for hosted traffic and P2HS Cloud usage. Separate from codegen.', 25000, 12000, 'usd', true, 30)
    """)


def downgrade() -> None:
    op.drop_table("workspace_wallet_alerts")
    op.drop_table("workspace_cloud_credit_policies")
    op.drop_table("cloud_usage_conversion_rates")
    op.drop_index("idx_cloud_credit_ledger_source", table_name="cloud_credit_ledger")
    op.drop_index("idx_cloud_credit_ledger_workspace", table_name="cloud_credit_ledger")
    op.drop_table("cloud_credit_ledger")
    op.drop_table("cloud_credit_purchases")
    op.drop_table("cloud_credit_packages")
    op.execute("""
        UPDATE subscription_plans
        SET limits = COALESCE(limits, '{}'::jsonb) || '{"included_ai_units": 500}'::jsonb
        WHERE LOWER(slug) = 'pro'
    """)
