"""Provider model catalog helpers for interactive model selection."""

from __future__ import annotations

from typing import Dict, List

import httpx

from armorer.config import ConfigManager

CUSTOM_MODEL_CHOICE = "Enter custom model ID..."

DEFAULT_MODELS: Dict[str, str] = {
    "openai": "gpt-5.4",
    "anthropic": "claude-sonnet-4-6",
    "gemini": "gemini-2.5-flash",
    "bedrock": "anthropic.claude-sonnet-4-6",
    "openrouter": "openai/gpt-5.4",
    "ollama": "llama3.1",
}

CURATED_MODELS: Dict[str, List[str]] = {
    "openai": ["gpt-5.4", "gpt-5.4-mini", "gpt-5.4-nano", "gpt-5", "gpt-4.1"],
    "anthropic": [
        "claude-opus-4-6",
        "claude-sonnet-4-6",
        "claude-haiku-4-5",
        "claude-haiku-4-5-20251001",
    ],
    "gemini": [
        "gemini-3.1-pro-preview",
        "gemini-3-flash-preview",
        "gemini-3.1-flash-lite-preview",
        "gemini-2.5-pro",
        "gemini-2.5-flash",
        "gemini-2.5-flash-lite",
    ],
    "bedrock": [
        "anthropic.claude-opus-4-6-v1",
        "anthropic.claude-sonnet-4-6",
        "anthropic.claude-haiku-4-5-20251001-v1:0",
        "us.anthropic.claude-sonnet-4-20250514-v1:0",
    ],
    "openrouter": [
        "openai/gpt-5.4",
        "openai/gpt-5.4-mini",
        "anthropic/claude-sonnet-4-6",
        "google/gemini-2.5-pro",
        "qwen/qwen-2.5-coder-32b-instruct",
    ],
    "ollama": ["llama3.1", "qwen2.5-coder:32b", "mistral", "phi4", "gemma3"],
}


def _dedupe_keep_order(values: List[str]) -> List[str]:
    out: List[str] = []
    seen = set()
    for raw in values:
        value = str(raw or "").strip()
        if not value or value in seen:
            continue
        seen.add(value)
        out.append(value)
    return out


def _safe_get_json(url: str, headers: Dict[str, str] | None = None) -> Dict:
    try:
        resp = httpx.get(url, headers=headers or {}, timeout=6.0)
        resp.raise_for_status()
        data = resp.json()
        return data if isinstance(data, dict) else {}
    except Exception:
        return {}


def _fetch_openai_models(cm: ConfigManager) -> List[str]:
    key = (cm.find_vault_key("OPENAI_API_KEY") or "").strip()
    if not key:
        return []
    data = _safe_get_json(
        "https://api.openai.com/v1/models",
        headers={"Authorization": f"Bearer {key}"},
    )
    items = data.get("data") or []
    return [it.get("id", "") for it in items if isinstance(it, dict)]


def _fetch_gemini_models(cm: ConfigManager) -> List[str]:
    key = (cm.find_vault_key("GEMINI_API_KEY") or "").strip()
    if not key:
        return []
    data = _safe_get_json(f"https://generativelanguage.googleapis.com/v1beta/models?key={key}")
    out: List[str] = []
    for item in data.get("models") or []:
        if not isinstance(item, dict):
            continue
        raw_name = str(item.get("name") or "").strip()
        if not raw_name:
            continue
        out.append(raw_name.split("/", 1)[-1])
    return out


def _fetch_openrouter_models() -> List[str]:
    data = _safe_get_json("https://openrouter.ai/api/v1/models")
    items = data.get("data") or []
    return [it.get("id", "") for it in items if isinstance(it, dict)]


def _fetch_ollama_models(cm: ConfigManager) -> List[str]:
    base = (cm.get_key("OLLAMA_BASE_URL") or "http://localhost:11434/v1/").strip()
    root = base.rstrip("/")
    if root.endswith("/v1"):
        root = root[:-3]
    tags_data = _safe_get_json(f"{root}/api/tags")
    out = [it.get("name", "") for it in (tags_data.get("models") or []) if isinstance(it, dict)]
    if out:
        return out

    models_data = _safe_get_json(f"{base.rstrip('/')}/models")
    return [it.get("id", "") for it in (models_data.get("data") or []) if isinstance(it, dict)]


def get_latest_models(provider: str, cm: ConfigManager) -> List[str]:
    provider_n = str(provider or "").strip().lower()
    if not provider_n:
        return []
    fetched: List[str] = []
    if provider_n == "openai":
        fetched = _fetch_openai_models(cm)
    elif provider_n == "gemini":
        fetched = _fetch_gemini_models(cm)
    elif provider_n == "openrouter":
        fetched = _fetch_openrouter_models()
    elif provider_n == "ollama":
        fetched = _fetch_ollama_models(cm)

    curated = CURATED_MODELS.get(provider_n, [])
    default_model = DEFAULT_MODELS.get(provider_n, "")
    merged = _dedupe_keep_order(fetched + curated + ([default_model] if default_model else []))
    return merged[:20]
