"""Маршруты OAuth-флоу через gnexus-gauth.

Поток: /auth/login → redirect на auth.gnexus.space (PKCE) → /auth/callback →
обмен code на токены → сессия (подписанная cookie через SessionMiddleware) →
redirect на return_to.

InMemory state/pkce store из gnexus-gauth достаточно для одного пользователя;
TODO(M0): заменить на постоянные хранилища до прод-деплоя (см. M0-заметки).
"""

from typing import Any

from fastapi import APIRouter, HTTPException, Request
from fastapi.responses import RedirectResponse

from app.auth.client import get_gauth_client
from app.config import get_settings

router = APIRouter(prefix="/auth", tags=["auth"])

SCOPES = ["openid", "email", "profile"]


@router.get("/login")
async def login(request: Request, return_to: str = "/") -> RedirectResponse:
    client = get_gauth_client()
    auth_request = client.build_authorization_request(return_to=return_to, scopes=SCOPES)
    # return_to запоминаем в сессии и забираем в callback после обмена code.
    request.session["return_to"] = return_to
    return RedirectResponse(auth_request.authorization_url)


@router.get("/callback")
async def callback(request: Request, code: str, state: str) -> RedirectResponse:
    client = get_gauth_client()

    try:
        token_set = client.exchange_authorization_code(code, state)
    except Exception as exc:  # gnexus_gauth.exceptions.* — общий обработчик на M0
        raise HTTPException(status_code=400, detail=f"OAuth callback failed: {exc}") from exc

    user = client.fetch_user(token_set.access_token)

    request.session["access_token"] = token_set.access_token
    request.session["refresh_token"] = token_set.refresh_token
    request.session["user"] = {
        "user_id": user.user_id,
        "email": user.email,
        "avatar_url": user.avatar_url,
        # Язык UI: SSO отдаёт profile.locale (default 'ru'); '' в поле — нет значения
        "locale": user.profile.get("locale") or "",
    }

    return_to = request.session.pop("return_to", "/")
    return RedirectResponse(return_to)


@router.get("/logout")
async def logout(request: Request) -> dict[str, bool]:
    request.session.clear()
    return {"ok": True}


@router.get("/me")
async def me(request: Request) -> dict[str, Any]:
    user = request.session.get("user")
    if not user:
        raise HTTPException(status_code=401, detail="Not authenticated")
    # Раздел профиля в системе авторизации (SSO): {base}/account
    account_url = get_settings().gauth_base_url.rstrip("/") + "/account"
    return {"user": user, "account_url": account_url}
