"""Convierte call specs del registry en una coleccion Hoppscotch importable.

Mitad "exportar al GUI" del puente entre el motor de replay del registry y
Hoppscotch. La funcion inversa es parse_hoppscotch_collection.
"""

from urllib.parse import urlparse


def _request_name(call: dict, fallback_index: int) -> str:
    """Deriva un nombre legible para la request a partir del metodo y el path.

    Args:
        call: call spec con (opcional) method y url.
        fallback_index: indice de la call dentro de la lista (no usado en el
            nombre derivado, reservado para desambiguar si hiciera falta).

    Returns:
        nombre del estilo "GET /api/search".
    """
    method = str(call.get("method") or "GET").upper()
    url = str(call.get("url") or "")
    path = urlparse(url).path or "/"
    return f"{method} {path}"


def _build_headers(call: dict) -> list[dict]:
    """Construye la lista de headers Hoppscotch desde el dict del call spec.

    Convierte el dict headers (preservando orden de insercion) a la lista
    [{"key", "value", "active": True}, ...] y, si el call spec trae cookies no
    vacias, anade un header extra "Cookie" al final con formato "k1=v1; k2=v2".

    Args:
        call: call spec con (opcional) headers y cookies.

    Returns:
        lista de headers Hoppscotch.
    """
    headers: list[dict] = []
    raw_headers = call.get("headers") or {}
    for key, value in raw_headers.items():
        headers.append({"key": key, "value": value, "active": True})

    cookies = call.get("cookies") or {}
    if cookies:
        cookie_value = "; ".join(f"{name}={val}" for name, val in cookies.items())
        headers.append({"key": "Cookie", "value": cookie_value, "active": True})

    return headers


def _build_body(call: dict) -> dict:
    """Construye el objeto body Hoppscotch segun body_type del call spec.

    Args:
        call: call spec con (opcional) body y body_type.

    Returns:
        dict con contentType y body. Si no hay body o el body_type es
        desconocido/None, ambos campos son None.
    """
    body = call.get("body")
    body_type = call.get("body_type")

    content_types = {
        "json": "application/json",
        "form": "application/x-www-form-urlencoded",
        "raw": "text/plain",
    }

    if body is None or body_type not in content_types:
        return {"contentType": None, "body": None}

    return {"contentType": content_types[body_type], "body": body}


def build_hoppscotch_collection(
    calls: list[dict],
    *,
    name: str = "Collection",
    request_names: list[str] | None = None,
) -> dict:
    """Convierte una lista de call specs en una coleccion Hoppscotch importable.

    Genera el formato canonico estable (coleccion v:1, request v:"2") que
    Hoppscotch migra a la ultima version al importar. Pura: sin I/O ni red,
    solo stdlib, determinista.

    Args:
        calls: lista de call specs (salida de har_extract_calls). Cada elemento
            es un dict con claves opcionales: method, url, headers, cookies,
            body, body_type. Otras claves (status, sets_cookies, ...) se ignoran.
        name: nombre de la coleccion Hoppscotch.
        request_names: nombres explicitos por request, alineados por indice. Si
            se pasa y existe el indice, sobreescribe el nombre derivado. None =
            derivar todos los nombres como "<METHOD> <path>".

    Returns:
        dict con la coleccion Hoppscotch: {"v": 1, "name", "folders": [],
        "requests": [...]}. JSON-serializable.
    """
    requests: list[dict] = []

    for index, call in enumerate(calls):
        if request_names is not None and index < len(request_names):
            req_name = request_names[index]
        else:
            req_name = _request_name(call, index)

        endpoint = str(call.get("url") or "")
        method = str(call.get("method") or "GET").upper()

        requests.append(
            {
                "v": "2",
                "endpoint": endpoint,
                "name": req_name,
                "params": [],
                "headers": _build_headers(call),
                "method": method,
                "auth": {"authType": "none", "authActive": True},
                "preRequestScript": "",
                "testScript": "",
                "body": _build_body(call),
                "requestVariables": [],
            }
        )

    return {
        "v": 1,
        "name": name,
        "folders": [],
        "requests": requests,
    }
