#!/usr/bin/env python3
from __future__ import annotations

import argparse
import json
import os
import sys
from pathlib import Path
from urllib import error, request


DEFAULT_BASE_URL = "https://gen.pollinations.ai"
DEFAULT_KEY_PATH = Path.home() / ".pollinations" / "credentials.json"

ALIASES = {
    "daily": "gpt-5.4-mini",
    "cheap": "gemini-flash-lite-3.1",
    "heavy": "gpt-5.5",
    "coding_primary": "qwen-coder",
    "coding_backup": "qwen-coder-large",
    "search": "perplexity-fast",
    "search_reasoning": "perplexity-reasoning",
    "vision_primary": "qwen-vision",
    "vision_heavy": "qwen-vision-pro",
    "guardrail": "qwen-safety",
    "text.daily": "gpt-5.4-mini",
    "text.cheap": "gemini-flash-lite-3.1",
    "text.heavy": "gpt-5.5",
    "text.coding_primary": "qwen-coder",
    "text.coding_backup": "qwen-coder-large",
    "text.search": "perplexity-fast",
    "text.search_reasoning": "perplexity-reasoning",
    "text.vision_primary": "qwen-vision",
    "text.vision_heavy": "qwen-vision-pro",
    "text.guardrail": "qwen-safety",
    "embeddings.primary": "openai-3-small",
    "embeddings.quality": "openai-3-large",
    "image.fast_preview": "zimage",
    "image.background_change": "kontext",
    "image.final_quality": "gptimage-large",
    "video.primary": "ltx-2",
    "video.backup": "wan",
    "audio.tts_primary": "qwen-tts-instruct",
    "audio.tts_fast": "qwen-tts",
    "audio.tts_premium": "elevenlabs",
}


def load_api_key() -> str:
    inline = os.getenv("POLLINATIONS_API_KEY", "").strip()
    if inline:
        return inline
    key_path = Path(os.getenv("POLLINATIONS_KEY_PATH", str(DEFAULT_KEY_PATH))).expanduser()
    data = json.loads(key_path.read_text(encoding="utf-8"))
    key = str(data.get("apiKey", "")).strip()
    if not key:
        raise RuntimeError(f"apiKey not found in {key_path}")
    return key


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Pollinations OpenAI-compatible chat helper.")
    parser.add_argument("prompt", nargs="?", help="Prompt. If omitted, stdin is used.")
    parser.add_argument("--model", default="text.daily", help="Model alias or exact model id.")
    parser.add_argument("--system", default="", help="Optional system prompt.")
    parser.add_argument("--temperature", type=float, default=0.2)
    parser.add_argument("--max-tokens", type=int, default=1200)
    parser.add_argument("--json", action="store_true", help="Print raw JSON.")
    parser.add_argument("--list-aliases", action="store_true")
    return parser.parse_args()


def main() -> int:
    args = parse_args()
    if args.list_aliases:
        print(json.dumps(ALIASES, ensure_ascii=False, indent=2, sort_keys=True))
        return 0

    prompt = args.prompt if args.prompt is not None else sys.stdin.read()
    prompt = prompt.strip()
    if not prompt:
        raise RuntimeError("prompt is empty")

    model = ALIASES.get(args.model.strip(), args.model.strip())
    messages = []
    if args.system.strip():
        messages.append({"role": "system", "content": args.system.strip()})
    messages.append({"role": "user", "content": prompt})

    base_url = os.getenv("POLLINATIONS_BASE_URL", DEFAULT_BASE_URL).rstrip("/")
    payload = {
        "model": model,
        "messages": messages,
        "temperature": args.temperature,
        "max_tokens": args.max_tokens,
    }
    req = request.Request(
        f"{base_url}/v1/chat/completions",
        data=json.dumps(payload).encode("utf-8"),
        headers={
            "Authorization": f"Bearer {load_api_key()}",
            "Content-Type": "application/json",
            "Accept": "application/json",
            "User-Agent": "curl/8.5 detmir-proxmox",
        },
        method="POST",
    )
    try:
        with request.urlopen(req, timeout=180) as resp:
            body = resp.read().decode("utf-8", errors="replace")
    except error.HTTPError as exc:
        body = exc.read().decode("utf-8", errors="replace")
        raise RuntimeError(f"pollinations http {exc.code}: {body[:2000]}") from exc

    data = json.loads(body)
    if args.json:
        print(json.dumps(data, ensure_ascii=False, indent=2))
        return 0

    choices = data.get("choices") or []
    if not choices:
        raise RuntimeError(f"no choices in response: {body[:2000]}")
    message = choices[0].get("message") or {}
    content = message.get("content")
    if isinstance(content, list):
        text = "\n".join(str(part.get("text", "")) for part in content if isinstance(part, dict))
    else:
        text = str(content or "")
    print(text.strip())
    return 0


if __name__ == "__main__":
    try:
        raise SystemExit(main())
    except Exception as exc:
        print(f"polli-chat error: {exc}", file=sys.stderr)
        raise SystemExit(1)
