"""
Alembic migration environment configuration.

Uses synchronous psycopg2 driver for migrations while the application
uses asyncpg at runtime. This is the standard pattern for Alembic with
async SQLAlchemy applications.
"""
from logging.config import fileConfig

from sqlalchemy import create_engine, pool
from sqlalchemy.engine import Connection

from alembic import context

# Import Base and all models to ensure metadata is complete
from app.database.session import Base
from app.models.db_models import (  # noqa: F401
    Game,
    GameCardsetLink,
    GameSession,
    Lineup,
    Play,
    Roll,
    RosterLink,
)

# Load settings for database URL
from app.config import get_settings

# Alembic Config object - provides access to the .ini file values
config = context.config

# Get database URL from settings and convert for sync driver (psycopg2)
settings = get_settings()
# Replace asyncpg with psycopg2 for synchronous migrations
sync_database_url = settings.database_url.replace("+asyncpg", "+psycopg2")
config.set_main_option("sqlalchemy.url", sync_database_url)

# Interpret the config file for Python logging
if config.config_file_name is not None:
    fileConfig(config.config_file_name)

# Target metadata for 'autogenerate' support
target_metadata = Base.metadata


def run_migrations_offline() -> None:
    """
    Run migrations in 'offline' mode.

    This configures the context with just a URL and not an Engine,
    generating SQL scripts without connecting to the database.
    """
    url = config.get_main_option("sqlalchemy.url")
    context.configure(
        url=url,
        target_metadata=target_metadata,
        literal_binds=True,
        dialect_opts={"paramstyle": "named"},
        compare_type=True,  # Detect column type changes
        compare_server_default=True,  # Detect server_default changes
    )

    with context.begin_transaction():
        context.run_migrations()


def do_run_migrations(connection: Connection) -> None:
    """Execute migrations using the provided connection."""
    context.configure(
        connection=connection,
        target_metadata=target_metadata,
        compare_type=True,
        compare_server_default=True,
    )

    with context.begin_transaction():
        context.run_migrations()


def run_migrations_online() -> None:
    """
    Run migrations in 'online' mode.

    Creates a synchronous engine and associates a connection with the context.
    """
    connectable = create_engine(
        config.get_main_option("sqlalchemy.url"),
        poolclass=pool.NullPool,
    )

    with connectable.connect() as connection:
        do_run_migrations(connection)

    connectable.dispose()


if context.is_offline_mode():
    run_migrations_offline()
else:
    run_migrations_online()
