"""Simple JWT-based admin authentication."""

import os
import secrets
from datetime import datetime, timedelta, timezone
from typing import Annotated

from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer

# python-jose is lighter than full jose stack; use PyJWT as fallback
try:
    from jose import JWTError, jwt as _jose_jwt  # type: ignore

    _BACKEND = "jose"
except ImportError:
    try:
        import jwt as _pyjwt  # type: ignore

        _BACKEND = "pyjwt"
    except ImportError:
        _BACKEND = "none"

SECRET_KEY = os.environ.get("JWT_SECRET", secrets.token_hex(32))
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = int(os.environ.get("JWT_EXPIRE_MINUTES", "60"))

# Admin credentials — override with env vars in production
ADMIN_USERNAME = os.environ.get("ADMIN_USERNAME", "admin")
ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "changeme")

bearer_scheme = HTTPBearer(auto_error=False)


def create_access_token(data: dict) -> str:
    payload = data.copy()
    expire = datetime.now(timezone.utc) + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    payload["exp"] = expire

    if _BACKEND == "jose":
        return _jose_jwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
    elif _BACKEND == "pyjwt":
        return _pyjwt.encode(payload, SECRET_KEY, algorithm=ALGORITHM)
    else:
        # Fallback: plain base64 "token" (dev-only, not secure)
        import base64, json
        return base64.urlsafe_b64encode(json.dumps(payload, default=str).encode()).decode()


def decode_token(token: str) -> dict:
    if _BACKEND == "jose":
        return _jose_jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
    elif _BACKEND == "pyjwt":
        return _pyjwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
    else:
        import base64, json
        return json.loads(base64.urlsafe_b64decode(token + "==").decode())


def verify_admin_token(
    credentials: Annotated[HTTPAuthorizationCredentials | None, Depends(bearer_scheme)],
) -> str:
    """FastAPI dependency — raises 401 if token is missing/invalid."""
    if not credentials:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Authentication required",
            headers={"WWW-Authenticate": "Bearer"},
        )
    try:
        payload = decode_token(credentials.credentials)
        username: str = payload.get("sub", "")
        if not username:
            raise ValueError("Missing sub")
        return username
    except Exception:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or expired token",
            headers={"WWW-Authenticate": "Bearer"},
        )
