import hashlib
import secrets

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

from app.config import get_settings

_bearer = HTTPBearer(auto_error=False)


def generate_server_key() -> str:
    """Plaintext-ключ агента. Показывается один раз при создании сервера."""
    return "ghm_" + secrets.token_urlsafe(24)


def hash_key(key: str) -> str:
    return hashlib.sha256(key.encode()).hexdigest()


def auth_mode_error() -> HTTPException:
    """401/403, когда браузер не залогинен в gnexus-auth (GHARD_AUTH_CLIENT_ID задан)."""
    return HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="not authenticated")


async def require_admin(
    request: Request,
    creds: HTTPAuthorizationCredentials | None = Depends(_bearer),
) -> None:
    """Доступ к API панели (данные, CRUD, MCP).

    Порядок:
    1. Bearer GHARD_ADMIN_TOKEN (если задан) — скрипты, MCP, curl.
    2. Агенты: заголовок X-Server-Key проверяется только в ingest-роутере.
    3. GHARD_AUTH_CLIENT_ID задан → браузер с валидной сессионной cookie.
    4. auth выключен и admin_token пуст → API открыт (личная панель).
    """
    settings = get_settings()
    token = settings.admin_token
    if token and creds is not None and creds.scheme.lower() == "bearer" and creds.credentials == token:
        return
    if settings.auth_client_id:
        from app.auth import SESSION_COOKIE, get_session

        session = await get_session(request.cookies.get(SESSION_COOKIE))
        if session is None:
            raise auth_mode_error()
        return
    if not token:
        return
    raise HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="invalid admin token",
    )