"""Flask middleware for JWT authentication."""

from flask import Flask, g, jsonify, request

from ..config import AuthSettings
from ..exceptions import AuthenticationError
from ..models import AuthenticatedUser
from ..token import get_key_cache, validate_token


def init_auth(app: Flask, settings: AuthSettings) -> None:
    """Register JWT auth middleware on a Flask app.

    Validates Bearer tokens on all /api/* routes. Stores the authenticated
    user on Flask's g.user for access in route handlers.

    Usage:
        from conduit_auth.flask import init_auth
        from conduit_auth import AuthSettings

        settings = AuthSettings()
        init_auth(app, settings)

        # In routes:
        from conduit_auth.flask import get_current_user
        user = get_current_user()
    """
    @app.before_request
    def _validate_auth():
        path = request.path

        # Skip excluded paths
        if path in settings.AUTH_EXCLUDE_PATHS:
            return None

        # Only protect /api/* routes
        if not path.startswith("/api/"):
            return None

        # Dev bypass
        if settings.AUTH_DISABLED:
            g.user = AuthenticatedUser(
                tenant_id="dev-tenant-00000000",
                user_id="dev-user-00000000",
                email="dev@localhost",
                display_name="Dev User",
                roles=[],
                raw_claims={},
            )
            return None

        # Extract Bearer token
        auth_header = request.headers.get("Authorization", "")
        if not auth_header.startswith("Bearer "):
            return (
                jsonify({"error": "Missing or invalid Authorization header"}),
                401,
            )
        token = auth_header[7:]

        # Validate
        try:
            jwks_keys = get_key_cache().get_keys(settings)
            user = validate_token(token, jwks_keys, settings)
        except AuthenticationError as e:
            return jsonify({"error": str(e)}), 401

        g.user = user
        return None


def get_current_user() -> AuthenticatedUser:
    """Get the authenticated user from Flask's request context.

    Returns:
        The AuthenticatedUser set by init_auth middleware.

    Raises:
        401 abort if no user is set (request wasn't authenticated).
    """
    user = getattr(g, "user", None)
    if user is None:
        from flask import abort

        abort(401)
    return user
