"""Actualiza una request REST existente en Hoppscotch.

Reconstruye el HoppRESTRequest canonico (reusando build_hoppscotch_collection
del registry) y lo aplica sobre una request existente via la mutation GraphQL
updateRequest del backend self-hosted. Protegida por GqlAuthGuard: el JWT de
sesion viaja en la cookie `access_token`.
"""

import json

import requests

from infra.build_hoppscotch_collection import build_hoppscotch_collection

_MUTATION = (
    "mutation($r:ID!,$d:UpdateTeamRequestInput!){"
    " updateRequest(requestID:$r, data:$d){ id title } }"
)


def hoppscotch_update_request(
    request_id: str,
    method: str,
    url: str,
    *,
    title: str | None = None,
    headers: dict | None = None,
    body: str | None = None,
    body_type: str | None = None,
    access_token: str,
    backend_url: str = "http://localhost:3170",
) -> dict:
    """Actualiza una request existente en Hoppscotch.

    Args:
        request_id: ID de la request a actualizar.
        method: metodo HTTP de la request (GET, POST, ...).
        url: endpoint de la request.
        title: nombre visible de la request en la GUI. None = derivar de
            method + path via build_hoppscotch_collection.
        headers: dict name->value de cabeceras de la request.
        body: cuerpo de la request como texto ya serializado.
        body_type: tipo de cuerpo ("json"|"form"|"raw"|None).
        access_token: JWT de sesion (de hoppscotch_login). Viaja en la cookie
            `access_token`, NO en el header Authorization.
        backend_url: base del backend Hoppscotch (sin barra final).

    Returns:
        Dict. En exito: ``{"status": "ok", "id": str, "title": str}``. En error
        (GraphQL errors, HTTP no 200, transporte): ``{"status": "error",
        "error": str, "data": ...}`` con el cuerpo GraphQL si lo hubo.
    """
    spec = {
        "method": method,
        "url": url,
        "headers": headers or {},
        "body": body,
        "body_type": body_type,
    }
    req_names = [title] if title else None
    req_item = build_hoppscotch_collection([spec], request_names=req_names)[
        "requests"
    ][0]

    payload = {
        "query": _MUTATION,
        "variables": {
            "r": request_id,
            "d": {
                "title": req_item["name"],
                "request": json.dumps(req_item),
            },
        },
    }

    try:
        resp = requests.post(
            f"{backend_url}/graphql",
            json=payload,
            cookies={"access_token": access_token},
            timeout=30.0,
        )
    except requests.RequestException as exc:
        return {"status": "error", "error": f"transport error: {exc}"}

    try:
        data = resp.json()
    except ValueError:
        return {
            "status": "error",
            "error": f"non-JSON response (HTTP {resp.status_code})",
        }

    if data.get("errors"):
        return {
            "status": "error",
            "error": "graphql errors",
            "data": data,
        }

    updated = (data.get("data") or {}).get("updateRequest")
    if not updated or not updated.get("id"):
        return {
            "status": "error",
            "error": "updateRequest returned no id",
            "data": data,
        }

    return {
        "status": "ok",
        "id": updated["id"],
        "title": updated.get("title"),
    }
