"""FastAPI dependency functions — auth, request utilities."""
from __future__ import annotations
from typing import Optional
from fastapi import HTTPException, Request, Security
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials

_bearer = HTTPBearer(auto_error=False)


def _extract_token(request: Request, credentials: Optional[HTTPAuthorizationCredentials]) -> Optional[str]:
    # 1. HTTPBearer Authorization header (highest trust)
    if credentials and getattr(credentials, "credentials", None):
        return credentials.credentials
    auth_header = request.headers.get("authorization", "")
    if auth_header.lower().startswith("bearer "):
        return auth_header[7:].strip()
    if auth_header.lower().startswith("apikey "):
        return auth_header[7:].strip()
    # 2. X-API-Key header
    key = request.headers.get("x-api-key") or request.headers.get("X-API-Key")
    if key:
        return key
    # 3. Cookie (server-issued, always valid if present) — checked BEFORE X-Session-Token
    cookie_tok = request.cookies.get("salmalm_token") or request.cookies.get("token")
    if cookie_tok:
        return cookie_tok
    # 4. X-Session-Token header (frontend sessionStorage token — may be stale)
    x_tok = request.headers.get("x-session-token", "").strip()
    if x_tok:
        return x_tok
    return None


async def require_auth(
    request: Request,
    credentials: Optional[HTTPAuthorizationCredentials] = Security(_bearer),
) -> dict:
    """Require authenticated user. Raises 401 if missing/invalid."""
    token = _extract_token(request, credentials)
    if not token:
        raise HTTPException(status_code=401, detail="Unauthorized")
    from salmalm.web.auth import extract_auth
    payload = extract_auth({"authorization": f"Bearer {token}"})
    if not payload:
        # Try as API key
        from salmalm.web.auth import extract_auth
        payload = extract_auth({"x-api-key": token})
    if not payload:
        raise HTTPException(status_code=401, detail="Invalid token")
    return payload


async def optional_auth(
    request: Request,
    credentials: Optional[HTTPAuthorizationCredentials] = Security(_bearer),
) -> Optional[dict]:
    """Optional auth — returns None if unauthenticated."""
    token = _extract_token(request, credentials)
    if not token:
        return None
    from salmalm.web.auth import extract_auth
    return extract_auth({"authorization": f"Bearer {token}"})
