"""HTTP client for B2Alpha Supabase edge functions."""

from __future__ import annotations

import json as _json
import sys
from typing import Any

import httpx

from .config import load_env_config

DEBUG = False


def _debug_request(method: str, url: str, headers: dict, body: Any = None) -> None:
    if not DEBUG:
        return
    print(f"\n{'='*60}", file=sys.stderr)
    print(f"DEBUG >>> {method} {url}", file=sys.stderr)
    for k, v in headers.items():
        val = v[:20] + "..." if k.lower() in ("authorization", "apikey") else v
        print(f"  {k}: {val}", file=sys.stderr)
    if body is not None:
        print(f"  Body: {_json.dumps(body, indent=2)}", file=sys.stderr)


def _debug_response(resp: httpx.Response) -> None:
    if not DEBUG:
        return
    print(f"DEBUG <<< {resp.status_code} {resp.reason_phrase}", file=sys.stderr)
    print(f"  URL: {resp.url}", file=sys.stderr)
    try:
        print(f"  Body: {_json.dumps(resp.json(), indent=2)}", file=sys.stderr)
    except Exception:
        print(f"  Body: {resp.text[:500]}", file=sys.stderr)
    print(f"{'='*60}\n", file=sys.stderr)


def _base_url() -> str:
    url, _ = load_env_config()
    return f"{url}/functions/v1"


def _anon_headers() -> dict[str, str]:
    _, anon_key = load_env_config()
    return {"apikey": anon_key, "Content-Type": "application/json"}


def _auth_headers(token: str) -> dict[str, str]:
    _, anon_key = load_env_config()
    return {
        "apikey": anon_key,
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
    }


def list_my_agents(token: str) -> list[dict[str, Any]]:
    """Fetch the authenticated user's agents via PostgREST."""
    from .auth import get_user_id

    uid = get_user_id(token)
    url, _ = load_env_config()
    rest_url = f"{url}/rest/v1/agents"
    headers = _auth_headers(token)
    params = {
        "select": "did,display_name,agent_type,public_key,status",
        "owner_user_id": f"eq.{uid}",
        "status": "eq.1",
    }
    _debug_request("GET", rest_url, headers, params)
    resp = httpx.get(rest_url, params=params, headers=headers, timeout=15)
    _debug_response(resp)
    if resp.status_code >= 400:
        return []
    return resp.json()


def register_agent(token: str, payload: dict[str, Any]) -> dict[str, Any]:
    url = f"{_base_url()}/agent-register"
    headers = _auth_headers(token)
    _debug_request("POST", url, headers, payload)
    resp = httpx.post(url, headers=headers, json=payload, timeout=15)
    _debug_response(resp)
    data = resp.json()
    if resp.status_code >= 400:
        raise RuntimeError(data.get("error", f"HTTP {resp.status_code}"))
    return data


def update_agent(token: str, payload: dict[str, Any]) -> dict[str, Any]:
    url = f"{_base_url()}/agent-update"
    headers = _auth_headers(token)
    _debug_request("PATCH", url, headers, payload)
    resp = httpx.patch(url, headers=headers, json=payload, timeout=15)
    _debug_response(resp)
    data = resp.json()
    if resp.status_code >= 400:
        raise RuntimeError(data.get("error", f"HTTP {resp.status_code}"))
    return data


def lookup_agent(did: str, token: str | None = None) -> dict[str, Any]:
    url = f"{_base_url()}/agent-lookup"
    headers = _auth_headers(token) if token else _anon_headers()
    _debug_request("GET", url, headers, {"did": did})
    resp = httpx.get(url, params={"did": did}, headers=headers, timeout=15)
    _debug_response(resp)
    data = resp.json()
    if resp.status_code >= 400:
        raise RuntimeError(data.get("error", f"HTTP {resp.status_code}"))
    return data


def search_phonebook(
    query: str | None = None,
    agent_type: str | None = None,
    limit: int = 20,
    token: str | None = None,
) -> dict[str, Any]:
    params: dict[str, str] = {"limit": str(limit)}
    if query:
        params["q"] = query
    if agent_type:
        params["type"] = agent_type
    url = f"{_base_url()}/agent-lookup"
    headers = _auth_headers(token) if token else _anon_headers()
    _debug_request("GET", url, headers, params)
    resp = httpx.get(url, params=params, headers=headers, timeout=15)
    _debug_response(resp)
    data = resp.json()
    if resp.status_code >= 400:
        raise RuntimeError(data.get("error", f"HTTP {resp.status_code}"))
    return data


def list_conversations(
    token: str,
    limit: int = 50,
    with_did: str | None = None,
    filter: str | None = None,
) -> dict[str, Any]:
    params: dict[str, str] = {"limit": str(limit)}
    if with_did:
        params["with"] = with_did
    if filter:
        params["filter"] = filter
    url = f"{_base_url()}/conversations-list"
    headers = _auth_headers(token)
    _debug_request("GET", url, headers, params)
    resp = httpx.get(url, params=params, headers=headers, timeout=15)
    _debug_response(resp)
    data = resp.json()
    if resp.status_code >= 400:
        raise RuntimeError(data.get("error", f"HTTP {resp.status_code}"))
    return data


def list_interaction_records(
    token: str,
    did: str,
    limit: int = 100,
) -> list[dict[str, Any]]:
    """Fetch recent interaction rows for one DID via PostgREST."""
    url, _ = load_env_config()
    rest_url = f"{url}/rest/v1/interactions"
    headers = _auth_headers(token)
    params = {
        "select": "interaction_id,participant_a_did,participant_b_did,messages,updated_at,ended_at",
        "or": f"(participant_a_did.eq.{did},participant_b_did.eq.{did})",
        "order": "updated_at.desc",
        "limit": str(limit),
    }
    _debug_request("GET", rest_url, headers, params)
    resp = httpx.get(rest_url, params=params, headers=headers, timeout=15)
    _debug_response(resp)
    data = resp.json()
    if resp.status_code >= 400:
        raise RuntimeError(data.get("error", f"HTTP {resp.status_code}"))
    return data


def get_conversation(token: str, interaction_id: str) -> dict[str, Any]:
    url = f"{_base_url()}/conversations-list"
    headers = _auth_headers(token)
    params = {"id": interaction_id}
    _debug_request("GET", url, headers, params)
    resp = httpx.get(url, params=params, headers=headers, timeout=15)
    _debug_response(resp)
    data = resp.json()
    if resp.status_code >= 400:
        raise RuntimeError(data.get("error", f"HTTP {resp.status_code}"))
    return data


def send_message(
    token: str,
    sender_did: str,
    recipient_did: str,
    message: dict[str, Any],
    interaction_id: str | None = None,
    on_behalf_of: str | None = None,
    close_interaction: bool = False,
) -> dict[str, Any]:
    payload: dict[str, Any] = {
        "sender_did": sender_did,
        "recipient_did": recipient_did,
        "message": message,
    }
    if interaction_id:
        payload["interaction_id"] = interaction_id
    if on_behalf_of:
        payload["on_behalf_of"] = on_behalf_of
    if close_interaction:
        payload["close_interaction"] = True
    url = f"{_base_url()}/interactions-upsert"
    headers = _auth_headers(token)
    _debug_request("POST", url, headers, payload)
    resp = httpx.post(url, headers=headers, json=payload, timeout=15)
    _debug_response(resp)
    data = resp.json()
    if resp.status_code >= 400:
        raise RuntimeError(data.get("error", f"HTTP {resp.status_code}"))
    return data
