"""Prompt yardımcısı — Ollama LLM ile Türkçe→İngilizce çeviri ve
prompt iyileştirme."""
import os
import requests
from typing import Optional

# Docker network için OLLAMA_HOST env var ile override edilebilir
# Örn: OLLAMA_HOST=http://ollama:11434 (compose service ismi)
OLLAMA_URL = os.environ.get("OLLAMA_HOST", "http://localhost:11434").rstrip("/")
# qwen3:8b düz yanıt verir (gpt-oss:20b reasoning model — token harcar)
DEFAULT_MODEL = os.environ.get("OLLAMA_MODEL", "qwen3:8b")
FALLBACK_MODELS = ["llama3.1:8b", "qwen2.5:7b", "mistral:7b", "gpt-oss:20b"]
# Büyük modeller (20B) yavaş olabilir — timeout uzun
TIMEOUT_LLM = int(os.environ.get("OLLAMA_TIMEOUT", "120"))


def ollama_var_mi() -> bool:
    """Ollama servisi açık mı?"""
    try:
        r = requests.get(f"{OLLAMA_URL}/api/tags", timeout=3)
        return r.status_code == 200
    except Exception:
        return False


def en_iyi_model() -> Optional[str]:
    """Mevcut modellerden en iyiyi seç."""
    try:
        r = requests.get(f"{OLLAMA_URL}/api/tags", timeout=3)
        if r.status_code != 200:
            return None
        modeller = [m["name"] for m in r.json().get("models", [])]
        for tercih in [DEFAULT_MODEL] + FALLBACK_MODELS:
            for m in modeller:
                if tercih in m or m == tercih:
                    return m
        return modeller[0] if modeller else None
    except Exception:
        return None


def llm_calistir(prompt: str, sistem: str = "", max_token: int = 500) -> str:
    """Ollama'da LLM çağrısı yap, sonucu string olarak döner.
    Türkçe karakterler için requests json= UTF-8 kullanır (varsayılan).
    Reasoning modelleri (gpt-oss) için /no_think direktifi eklenir."""
    model = en_iyi_model()
    if not model:
        print("[Prompt LLM] Ollama modeli bulunamadı")
        return ""
    # Reasoning modelleri için thinking'i devre dışı bırak
    is_reasoning = "gpt-oss" in model.lower() or "thinking" in model.lower()
    if is_reasoning:
        # Daha çok token ver, reasoning + cevap için
        max_token = max(max_token, 1500)
    try:
        body = {
            "model": model,
            "prompt": prompt,
            "system": sistem,
            "stream": False,
            "options": {
                "num_predict": max_token,
                "temperature": 0.7,
            },
        }
        # qwen3 ve diğer reasoning modeller için /think disable
        if "qwen3" in model.lower() or is_reasoning:
            body["think"] = False
        r = requests.post(
            f"{OLLAMA_URL}/api/generate",
            json=body,
            timeout=TIMEOUT_LLM,
        )
        if r.status_code != 200:
            print(f"[Prompt LLM] HTTP {r.status_code}: {r.text[:200]}")
            return ""
        data = r.json()
        cevap = (data.get("response") or "").strip()
        # Boş response + thinking varsa, thinking'in son kısmını kullan (fallback)
        if not cevap and data.get("thinking"):
            print(f"[Prompt LLM] {model} reasoning'de takıldı, thinking'den çek")
            think = data.get("thinking", "")
            # Son satırdaki cümleyi al
            satirlar = [s.strip() for s in think.split("\n") if s.strip()]
            if satirlar:
                cevap = satirlar[-1]
        return cevap
    except requests.Timeout:
        print(f"[Prompt LLM] Timeout ({TIMEOUT_LLM}sn) — daha küçük model dene")
        return ""
    except Exception as e:
        print(f"[Prompt LLM] hata: {e}")
        return ""


def turkce_to_ingilizce(turkce: str) -> str:
    """Türkçe açıklamayı SDXL için optimize edilmiş İngilizce prompt'a çevir."""
    if not turkce.strip():
        return ""
    sistem = (
        "You are an expert SDXL prompt engineer. Convert Turkish descriptions "
        "to high-quality English prompts for image generation. Focus on visual "
        "details: subject, composition, lighting, mood, style. Use comma-separated "
        "keywords. Add quality boosters like 'professional photography, "
        "8k, masterpiece, sharp focus, detailed'. Keep it under 100 words. "
        "Return ONLY the English prompt, no explanation."
    )
    return llm_calistir(turkce, sistem, max_token=200)


def prompt_gelistir(eksik_prompt: str, kategori: str = "genel") -> str:
    """Kısa/eksik İngilizce prompt'u uzunlat ve detaylandır.
    kategori: 'karakter', 'mekan', 'urun', 'genel'."""
    if not eksik_prompt.strip():
        return ""
    sistem_basla = {
        "karakter": (
            "You are an SDXL prompt engineer specializing in character/portrait "
            "generation. Enhance this prompt by adding: lighting (soft natural, "
            "studio, golden hour), facial expression details, pose, clothing "
            "specifics, background, professional quality boosters. Keep coherent."
        ),
        "mekan": (
            "You are an SDXL prompt engineer specializing in scene/environment "
            "generation. Enhance with: lighting, atmosphere, time of day, "
            "weather, architectural details, mood, perspective, depth, color palette."
        ),
        "urun": (
            "You are an SDXL prompt engineer specializing in product/commercial "
            "photography. Enhance with: studio lighting, white/branded background, "
            "shadows, reflections, material details, clean composition, "
            "advertising quality."
        ),
        "genel": (
            "You are an SDXL prompt engineer. Enhance this prompt by adding "
            "professional details: lighting, composition, quality boosters, "
            "art direction. Keep it visual and specific."
        ),
    }
    sistem = sistem_basla.get(kategori, sistem_basla["genel"]) + (
        " Output ONLY the enhanced English prompt, no explanation. Under 120 words."
    )
    return llm_calistir(eksik_prompt, sistem, max_token=300)


def sihirbaz_prompt_olustur(girdi: dict, kategori: str) -> str:
    """Sihirbaz adımlarından dolu girdiyi profesyonel prompt'a çevir.
    girdi: {'isim': '...', 'yas': '25', 'sac': 'kahverengi', 'kiyafet': 'kırmızı elbise', ...}
    kategori: 'karakter' | 'mekan' | 'urun'.
    """
    sistem_basla = {
        "karakter": (
            "Convert this character description (in Turkish/mixed) to a "
            "professional English SDXL prompt. Order: physical traits, clothing, "
            "expression, pose, background, lighting, quality. Comma-separated."
        ),
        "mekan": (
            "Convert this scene description to a professional English SDXL prompt. "
            "Order: location type, time/atmosphere, lighting, weather, key objects, "
            "perspective, mood, quality."
        ),
        "urun": (
            "Convert this product description to a professional English SDXL prompt. "
            "Order: product type, material/color, setting (studio/lifestyle), "
            "lighting, composition, advertising quality boosters."
        ),
    }
    sistem = sistem_basla.get(kategori, sistem_basla["karakter"]) + (
        " Output ONLY the prompt, comma-separated, under 100 words."
    )
    # Girdiyi düz metin'e çevir
    girdi_str = "\n".join(f"{k}: {v}" for k, v in girdi.items() if v)
    return llm_calistir(girdi_str, sistem, max_token=300)
