"""راه‌اندازی SQLAlchemy 2.x به‌صورت async.

- Base declarative مشترک همه مدل‌ها
- Engine و session factory
- Dependency برای دریافت AsyncSession در FastAPI
"""
from __future__ import annotations

from collections.abc import AsyncGenerator

from sqlalchemy.ext.asyncio import (
    AsyncSession,
    async_sessionmaker,
    create_async_engine,
)
from sqlalchemy.orm import DeclarativeBase

from app.core.config import settings


class Base(DeclarativeBase):
    """پایه declarative مشترک برای همه مدل‌های Core."""


engine = create_async_engine(
    settings.database_url,
    echo=settings.db_echo,
    pool_pre_ping=True,
    future=True,
)

AsyncSessionLocal = async_sessionmaker(
    bind=engine,
    class_=AsyncSession,
    expire_on_commit=False,
    autoflush=False,
)


async def get_db() -> AsyncGenerator[AsyncSession, None]:
    """Dependency: یک AsyncSession در طول عمر request فراهم می‌کند.

    در صورت بروز خطا rollback و در پایان session بسته می‌شود.
    """
    async with AsyncSessionLocal() as session:
        try:
            yield session
        except Exception:
            await session.rollback()
            raise
