from __future__ import annotations

from quart import session as qsession, g
from sqlalchemy import select
from sqlalchemy.orm import selectinload

from shared.models.user import User
from shared.models.ghost_membership_entities import UserNewsletter


async def load_user_by_id(session, user_id: int):
    """Load a user by ID with labels and newsletters eagerly loaded."""
    stmt = (
        select(User)
        .options(
            selectinload(User.labels),
            selectinload(User.user_newsletters).selectinload(
                UserNewsletter.newsletter
            ),
        )
        .where(User.id == user_id)
    )
    result = await session.execute(stmt)
    return result.scalar_one_or_none()


async def load_current_user():
    uid = qsession.get("uid")
    if not uid:
        g.user = None
        g.rights = {"admin": False}
        return

    # User table lives in the account DB — use account session when
    # the per-request session (g.s) targets a different database.
    from shared.db.session import DATABASE_URL, DATABASE_URL_ACCOUNT
    if DATABASE_URL_ACCOUNT != DATABASE_URL:
        from shared.db.session import get_account_session
        async with get_account_session() as s:
            g.user = await load_user_by_id(s, uid)
            # Expunge so the object is usable outside this session
            if g.user:
                s.expunge(g.user)
    else:
        g.user = await load_user_by_id(g.s, uid)

    g.rights = {l.name: True for l in g.user.labels} if g.user else {}
