"""
Auth contexts for mizan Allauth integration.

These are the core auth primitives that the frontend allauth module depends on.
Separated into two concerns:

- auth_status: Authentication state and permission guards (fast, no DB hit with JWT)
- user: Full user profile data (may require DB query for JWT auth)

Both are registered as global contexts for SSR hydration.
"""

from django.http import HttpRequest
from pydantic import BaseModel

from mizan.client import client


# =============================================================================
# Auth Status Context
# =============================================================================


class AuthStatusOutput(BaseModel):
    """Authentication status and permission guards."""

    is_authenticated: bool
    user_id: int | None = None
    is_staff: bool = False
    is_superuser: bool = False


@client(context="global")
def auth_status(request: HttpRequest) -> AuthStatusOutput:
    """
    Auth status context - provides authentication state and guards.

    This works identically for both session and JWT auth. The data comes
    from the request.user object (either full User or JWTUser with claims).

    Frontend:
        const auth = useAuthStatus()
        if (auth.is_authenticated) { ... }
        if (auth.is_staff) { ... }
    """
    user = request.user

    if not user.is_authenticated:
        return AuthStatusOutput(is_authenticated=False)

    return AuthStatusOutput(
        is_authenticated=True,
        user_id=user.id,
        is_staff=user.is_staff,
        is_superuser=user.is_superuser,
    )


# =============================================================================
# User Profile Context
# =============================================================================


class UserOutput(BaseModel):
    """Full user profile data."""

    id: int
    email: str
    first_name: str = ""
    last_name: str = ""


@client(context="global")
def user(request: HttpRequest) -> UserOutput | None:
    """
    User profile context - provides full user data.

    Unlike auth_status, this may require a DB query (for JWT auth where
    the user object is a minimal JWTUser with only claims).

    Returns None if not authenticated.

    Frontend:
        const user = useUser()
        if (user) {
            console.log(user.email)
        }
    """
    req_user = request.user

    if not req_user.is_authenticated:
        return None

    # Check if we have full user data or just JWT claims
    if hasattr(req_user, "email") and req_user.email:
        # Full User object (session auth)
        return UserOutput(
            id=req_user.id,
            email=req_user.email,
            first_name=getattr(req_user, "first_name", "") or "",
            last_name=getattr(req_user, "last_name", "") or "",
        )

    # JWTUser - need to fetch from DB
    from django.contrib.auth import get_user_model

    User = get_user_model()

    try:
        db_user = User.objects.get(pk=req_user.id)
        return UserOutput(
            id=db_user.id,
            email=db_user.email,
            first_name=db_user.first_name or "",
            last_name=db_user.last_name or "",
        )
    except User.DoesNotExist:
        return None
