"""Crea una request REST dentro de una team collection de Hoppscotch.

Construye el HoppRESTRequest canonico (reusando build_hoppscotch_collection del
registry) y lo inserta en una team collection via la mutation GraphQL
createRequestInCollection del backend self-hosted. La mutation esta 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($c:ID!,$d:CreateTeamRequestInput!){"
    " createRequestInCollection(collectionID:$c, data:$d){ id title } }"
)


def hoppscotch_create_request(
    collection_id: str,
    method: str,
    url: str,
    *,
    title: str | None = None,
    headers: dict | None = None,
    body: str | None = None,
    body_type: str | None = None,
    team_id: str | None = None,
    access_token: str,
    backend_url: str = "http://localhost:3170",
) -> dict:
    """Crea una request en una team collection de Hoppscotch.

    Args:
        collection_id: ID de la team collection donde insertar la request.
        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).
        team_id: ID de la team duena de la collection. Requerido por las
            versiones del backend cuyo CreateTeamRequestInput exige `teamID`
            (el self-host de referencia lo exige). Si el backend no lo pide,
            dejar 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]

    data: dict = {
        "title": req_item["name"],
        "request": json.dumps(req_item),
    }
    if team_id is not None:
        data["teamID"] = team_id

    payload = {
        "query": _MUTATION,
        "variables": {
            "c": collection_id,
            "d": data,
        },
    }

    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,
        }

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

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