import json
import sys

import httpx

from llamapass_cli.config import load


def _get_client():
    cfg = load()
    url = cfg["url"].rstrip("/")
    api_key = cfg.get("api_key", "")
    if not api_key:
        print("Error: no API key configured. Run: llamapass config set-key <key>")
        sys.exit(1)
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    }
    return url, headers


def list_models():
    url, headers = _get_client()
    try:
        resp = httpx.get(f"{url}/ollama/api/tags", headers=headers, timeout=30)
        resp.raise_for_status()
        data = resp.json()
        models = data.get("models", [])
        if not models:
            print("No models available.")
            return
        print(f"{'NAME':<40} {'SIZE':<12} {'MODIFIED'}")
        for m in models:
            name = m.get("name", "?")
            size_gb = m.get("size", 0) / (1024**3)
            modified = m.get("modified_at", "?")[:19]
            print(f"{name:<40} {size_gb:<12.1f}GB {modified}")
    except httpx.ConnectError:
        print(f"Error: cannot connect to {url}")
        sys.exit(1)
    except httpx.HTTPStatusError as e:
        _handle_http_error(e.response)


def chat_stream(model, messages):
    url, headers = _get_client()
    payload = {
        "model": model,
        "messages": messages,
        "stream": True,
    }
    try:
        with httpx.stream(
            "POST",
            f"{url}/ollama/api/chat",
            json=payload,
            headers=headers,
            timeout=None,
        ) as resp:
            if resp.status_code != 200:
                _handle_http_error(resp)
                return ""
            full_response = []
            for line in resp.iter_lines():
                if not line:
                    continue
                try:
                    data = json.loads(line)
                    content = data.get("message", {}).get("content", "")
                    if content:
                        print(content, end="", flush=True)
                        full_response.append(content)
                    if data.get("done"):
                        break
                except json.JSONDecodeError:
                    continue
            print()
            return "".join(full_response)
    except httpx.ConnectError:
        print(f"\nError: cannot connect to {url}")
        sys.exit(1)


def _handle_http_error(resp):
    try:
        data = resp.json()
        error = data.get("error", resp.status_code)
    except Exception:
        error = resp.status_code

    messages = {
        401: "Invalid API key. Run: llamapass config set-key <key>",
        403: f"Access denied: {error}",
        429: "Rate limited. Try again later.",
        502: "LlamaPass server cannot reach upstream Ollama.",
    }
    print(f"Error: {messages.get(resp.status_code, f'HTTP {resp.status_code}: {error}')}")
    sys.exit(1)
