"""
Cloud API Client for El Gringo CLI
====================================

When api_url is configured in ~/.elgringo/config.yml, the CLI proxies
requests to the cloud API instead of running agents locally.

Config example (~/.elgringo/config.yml):
    api_url: https://ai.chatterfix.com
    api_key: your-key-here
"""

import json
import os
import urllib.parse
import urllib.request
import urllib.error
from typing import Optional, Dict, Any, List


class CloudClient:
    """Lightweight HTTP client for El Gringo cloud API. Zero extra deps."""

    def __init__(self, base_url: str = "", api_key: str = ""):
        self.base_url = (
            base_url
            or os.environ.get("ELGRINGO_API_URL", "")
        ).rstrip("/")
        self.api_key = (
            api_key
            or os.environ.get("ELGRINGO_API_KEY", "")
        )

    @property
    def is_configured(self) -> bool:
        """True if a cloud API URL is set."""
        return bool(self.base_url)

    def _request(
        self,
        method: str,
        path: str,
        body: Optional[dict] = None,
        timeout: int = 120,
    ) -> dict:
        """Make an HTTP request. Returns parsed JSON or error dict."""
        url = f"{self.base_url}{path}"
        headers = {"Content-Type": "application/json", "Accept": "application/json"}
        if self.api_key:
            headers["Authorization"] = f"Bearer {self.api_key}"
        data = json.dumps(body).encode() if body else None
        req = urllib.request.Request(url, data=data, headers=headers, method=method)
        try:
            with urllib.request.urlopen(req, timeout=timeout) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            err = e.read().decode() if e.fp else str(e)
            return {"error": f"HTTP {e.code}: {err[:500]}"}
        except urllib.error.URLError as e:
            return {"error": f"Connection failed: {e.reason}"}
        except Exception as e:
            return {"error": str(e)}

    # ── Convenience methods ──────────────────────────────────────

    def health(self) -> dict:
        return self._request("GET", "/v1/health", timeout=10)

    def agents(self) -> list:
        result = self._request("GET", "/v1/agents", timeout=10)
        return result if isinstance(result, list) else []

    def ask(self, prompt: str, agent: Optional[str] = None, context: str = "") -> dict:
        body: Dict[str, Any] = {"prompt": prompt, "context": context}
        if agent:
            body["agent"] = agent
        return self._request("POST", "/v1/ask", body)

    def collaborate(
        self,
        prompt: str,
        mode: str = "auto",
        context: str = "",
        agents: Optional[List[str]] = None,
    ) -> dict:
        body: Dict[str, Any] = {"prompt": prompt, "mode": mode, "context": context}
        if agents:
            body["agents"] = agents
        return self._request("POST", "/v1/collaborate", body, timeout=180)

    def costs(self) -> dict:
        return self._request("GET", "/v1/costs", timeout=10)


def get_cloud_client() -> Optional[CloudClient]:
    """Return a CloudClient if api_url is configured, else None."""
    client = CloudClient()
    return client if client.is_configured else None
