from collections.abc import AsyncGenerator
from fastapi import Request
from sqlalchemy.ext.asyncio import (
    AsyncEngine,
    create_async_engine,
    async_sessionmaker,
    AsyncSession,
)
from sqlalchemy import text
from utils.db_utils import get_database_url_and_connect_args


database_url, connect_args = get_database_url_and_connect_args()

sql_engine: AsyncEngine = create_async_engine(database_url, connect_args=connect_args)
async_session_maker = async_sessionmaker(sql_engine, expire_on_commit=False)


async def get_async_session(request: Request = None) -> AsyncGenerator[AsyncSession, None]:
    """
    Get async database session with RLS (Row-Level Security) context.

    Sets PostgreSQL session variables for RLS policies based on authenticated user:
    - app.current_user_id: UUID of authenticated user
    - app.user_role: User's role (super_admin, client_admin, user)
    """
    async with async_session_maker() as session:
        # Set RLS session variables if user is authenticated
        if request and hasattr(request.state, "user") and request.state.user:
            user = request.state.user
            try:
                # PostgreSQL SET LOCAL doesn't support parameterized queries
                # Must use string formatting (safe because user.id is UUID and role is enum)
                await session.execute(
                    text(f"SET LOCAL app.current_user_id = '{user.id}'")
                )
                await session.execute(
                    text(f"SET LOCAL app.user_role = '{user.role}'")
                )
            except Exception as e:
                # Log but don't fail - RLS variables are defense-in-depth
                print(f"Warning: Failed to set RLS variables: {e}")

        yield session


async def create_db_and_tables():
    """No-op: migrations are now handled by Alembic."""
    pass
