# -*- coding: utf-8 -*-
"""
异步数据库引擎与会话管理
使用 SQLAlchemy 2.0 异步模式 + asyncpg 驱动，配置连接池参数。
提供 get_db() 依赖注入函数供 FastAPI 路由使用。
"""

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

# ---- 异步引擎 (带连接池配置) ----
engine = create_async_engine(
    settings.DATABASE_URL,
    echo=settings.DEBUG,       # DEBUG 模式下打印 SQL
    pool_size=20,              # 连接池常驻连接数
    max_overflow=10,           # 超出 pool_size 后允许的临时连接数
    pool_pre_ping=True,        # 每次取连接前探测存活，防止用到已断开的连接
    pool_recycle=3600,         # 连接最大存活时间(秒)，防止数据库端主动断连
)

# ---- 异步会话工厂 ----
AsyncSessionLocal = async_sessionmaker(
    bind=engine,
    class_=AsyncSession,
    expire_on_commit=False,    # 提交后不过期对象属性，避免 lazy load 异常
)


# ---- ORM 基类 ----
class Base(DeclarativeBase):
    """所有 ORM 模型必须继承此基类，Alembic 通过 Base.metadata 自动检测表结构变更。"""
    pass


# ---- 依赖注入：获取数据库会话 ----
async def get_db() -> AsyncGenerator[AsyncSession, None]:
    """
    FastAPI Depends() 专用生成器。
    每个请求获取独立会话，请求结束后自动关闭，异常时自动回滚。
    用法: db: AsyncSession = Depends(get_db)
    """
    async with AsyncSessionLocal() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise
        finally:
            await session.close()
