"""Add Postgres support with JSONB and timezone-aware timestamps

Revision ID: 18001fbb959a
Revises: 89ab3b24b597
Create Date: 2025-10-23 14:07:09.002036

"""

from collections.abc import Sequence

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

# revision identifiers, used by Alembic.
revision: str = "18001fbb959a"
down_revision: str | None = "89ab3b24b597"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    # Skip for SQLite - it doesn't support ALTER COLUMN TYPE
    # SQLite already uses JSON and DATETIME, variants handle the differences
    bind = op.get_bind()
    if bind.dialect.name == "sqlite":
        return

    op.alter_column(
        "evaloutput",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        existing_nullable=False,
    )
    op.alter_column(
        "evaloutput",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "evaloutput",
        "deleted_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "evaloutput",
        "output",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        type_=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "event",
        "data",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        type_=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "created_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        existing_nullable=False,
    )
    op.alter_column(
        "node",
        "updated_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "deleted_at",
        existing_type=postgresql.TIMESTAMP(),
        type_=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "dep_ids",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        type_=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "handler_input",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        type_=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "filter",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        type_=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "validator",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        type_=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "conditions",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        type_=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "additional_meta",
        existing_type=postgresql.JSON(astext_type=sa.Text()),
        type_=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        existing_nullable=True,
    )
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    # Skip for SQLite - it doesn't support ALTER COLUMN TYPE
    bind = op.get_bind()
    if bind.dialect.name == "sqlite":
        return

    op.alter_column(
        "node",
        "additional_meta",
        existing_type=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        type_=postgresql.JSON(astext_type=sa.Text()),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "conditions",
        existing_type=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        type_=postgresql.JSON(astext_type=sa.Text()),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "validator",
        existing_type=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        type_=postgresql.JSON(astext_type=sa.Text()),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "filter",
        existing_type=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        type_=postgresql.JSON(astext_type=sa.Text()),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "handler_input",
        existing_type=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        type_=postgresql.JSON(astext_type=sa.Text()),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "dep_ids",
        existing_type=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        type_=postgresql.JSON(astext_type=sa.Text()),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "deleted_at",
        existing_type=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "updated_at",
        existing_type=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "node",
        "created_at",
        existing_type=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    op.alter_column(
        "event",
        "data",
        existing_type=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        type_=postgresql.JSON(astext_type=sa.Text()),
        existing_nullable=True,
    )
    op.alter_column(
        "evaloutput",
        "output",
        existing_type=sa.JSON().with_variant(
            postgresql.JSONB(astext_type=sa.Text()), "postgresql"
        ),
        type_=postgresql.JSON(astext_type=sa.Text()),
        existing_nullable=True,
    )
    op.alter_column(
        "evaloutput",
        "deleted_at",
        existing_type=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "evaloutput",
        "updated_at",
        existing_type=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=True,
    )
    op.alter_column(
        "evaloutput",
        "created_at",
        existing_type=sa.DateTime(timezone=True).with_variant(
            postgresql.TIMESTAMP(timezone=True), "postgresql"
        ),
        type_=postgresql.TIMESTAMP(),
        existing_nullable=False,
    )
    # ### end Alembic commands ###
