import os
import jwt
from jwt import PyJWKClient
from fastapi import Request, HTTPException, status

from pif_compiler.functions.common_log import get_logger

logger = get_logger()

SUPABASE_URL = os.getenv("SUPABASE_URL", "")

# Client JWKS inizializzato una volta sola — caching automatico delle chiavi pubbliche
_jwks_client: PyJWKClient | None = None


def _get_jwks_client() -> PyJWKClient:
    global _jwks_client
    if _jwks_client is None:
        if not SUPABASE_URL:
            logger.error("SUPABASE_URL non configurato")
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Configurazione auth mancante sul server"
            )
        _jwks_client = PyJWKClient(f"{SUPABASE_URL}/auth/v1/.well-known/jwks.json")
    return _jwks_client


def verify_jwt(token: str) -> dict:
    """Verifica il JWT Supabase tramite JWKS (RS256/ES256). Ritorna il payload decodificato."""
    try:
        client = _get_jwks_client()
        signing_key = client.get_signing_key_from_jwt(token)
        payload = jwt.decode(
            token,
            signing_key.key,
            algorithms=["RS256", "ES256"],
            audience="authenticated",
        )
        return payload
    except jwt.ExpiredSignatureError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Token scaduto"
        )
    except jwt.InvalidTokenError as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=f"Token non valido: {e}"
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"verify_jwt: errore inatteso — {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Errore nella verifica del token"
        )


def get_current_user(request: Request) -> dict:
    """FastAPI dependency: estrae e verifica il JWT dall'header Authorization."""
    auth_header = request.headers.get("Authorization", "")
    if not auth_header.startswith("Bearer "):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Authorization header mancante o malformato"
        )
    token = auth_header.removeprefix("Bearer ")
    return verify_jwt(token)
