"""User context extraction for audit logging.

This module provides helpers to get the current authenticated user's
context for audit logging purposes.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from mcp_eregistrations_bpa.auth.token_manager import TokenManager


def get_token_manager(instance_id: str | None = None) -> TokenManager:
    """Get the token manager instance for the given instance.

    Uses late import to avoid circular dependency.

    Args:
        instance_id: Instance slug. None falls back to env-var default.

    Returns:
        The TokenManager for the given instance.
    """
    from mcp_eregistrations_bpa.server import get_token_manager as _get_tm

    return _get_tm(instance_id)


class NotAuthenticatedError(Exception):
    """Raised when user is not authenticated for audit operations."""

    pass


def get_current_user_email(instance: str | None = None) -> str:
    """Get the current authenticated user's email for audit logging.

    This function should be called before any write operation to capture
    the user context for the audit log.

    Args:
        instance: Named instance profile (e.g. "elsalvador-dev") or None
            to use the env-var default instance.

    Returns:
        The authenticated user's email address.

    Raises:
        NotAuthenticatedError: If no user is authenticated or email unavailable.
    """
    instance_id: str | None = None
    if instance is not None:
        from mcp_eregistrations_bpa.config import resolve_instance_config

        instance_id = resolve_instance_config(instance).instance_id
    token_manager = get_token_manager(instance_id)

    if not token_manager.is_authenticated():
        raise NotAuthenticatedError(
            "Cannot perform write operation: User not authenticated. "
            "Run auth_login first."
        )

    if token_manager.is_token_expired():
        raise NotAuthenticatedError(
            "Cannot perform write operation: Session expired. Run auth_login again."
        )

    email = token_manager.user_email
    if not email:  # Catches None, empty string, and whitespace-only
        raise NotAuthenticatedError(
            "Cannot perform write operation: User email not available. "
            "Please re-authenticate."
        )

    return email
