"""
Database engine and session management.

Provides async SQLAlchemy engine and session factory for dependency injection.
Supports dual database connections for mtgonline app and mtgjson data.
"""
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy.orm import DeclarativeBase
from app.core.settings import get_settings

settings = get_settings()

# Primary database engine (mtgonline app)
engine = create_async_engine(
    settings.DATABASE_URL,
    echo=settings.DEBUG,
    pool_pre_ping=True,
    pool_size=20,
    max_overflow=10,
)

async_session = async_sessionmaker(
    engine,
    class_=AsyncSession,
    expire_on_commit=False,
)

# Secondary database engine (mtgjson data)
mtg_engine = create_async_engine(
    settings.MTG_DATABASE_URL,
    echo=settings.DEBUG,
    pool_pre_ping=True,
    pool_size=10,
    max_overflow=5,
)

mtg_async_session = async_sessionmaker(
    mtg_engine,
    class_=AsyncSession,
    expire_on_commit=False,
)

# Mirror engine (same as primary — mirrors live in mtgo_platform)
mirror_engine = engine
mirror_async_session = async_session


async def get_db() -> AsyncSession:
    """FastAPI dependency that provides a database session for the mtgonline app."""
    async with async_session() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise
        finally:
            await session.close()


async def mtg_get_db() -> AsyncSession:
    """FastAPI dependency that provides a database session for mtgjson data."""
    async with mtg_async_session() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise
        finally:
            await session.close()


async def mirror_get_db() -> AsyncSession:
    """FastAPI dependency that provides a database session for mirror operations."""
    async with mirror_async_session() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise
        finally:
            await session.close()


class Base(DeclarativeBase):
    """Base class for all ORM models."""
    pass


__all__ = [
    "Base",
    "get_db",
    "async_session",
    "engine",
    "mtg_get_db",
    "mtg_async_session",
    "mtg_engine",
    "mirror_get_db",
    "mirror_async_session",
    "mirror_engine",
]
