"""GPU-Video-Encoding für Kunden-Render (AMD AMF / NVIDIA NVENC)."""

from __future__ import annotations

import subprocess
from functools import lru_cache


@lru_cache(maxsize=1)
def ffmpeg_encoders() -> set[str]:
    try:
        from jam.tiktok_remix import _find_ffmpeg

        ff = _find_ffmpeg()
        if not ff:
            return set()
        r = subprocess.run(
            [ff, "-hide_banner", "-encoders"],
            capture_output=True,
            text=True,
            timeout=20,
            encoding="utf-8",
            errors="replace",
        )
        enc: set[str] = set()
        for line in (r.stdout or "").splitlines():
            parts = line.split()
            if len(parts) >= 2 and parts[0].startswith("V"):
                enc.add(parts[1].strip())
        return enc
    except (subprocess.SubprocessError, OSError):
        return set()


def gpu_vendor() -> str:
    try:
        from jam.wan2gp_local import detect_gpu

        return str(detect_gpu().get("vendor") or "").lower()
    except Exception:
        return ""


def pick_video_encoder(*, prefer_gpu: bool = True) -> dict:
    """Besten FFmpeg-Encoder wählen (Kunden-Render auf lokaler GPU)."""
    if not prefer_gpu:
        return {"codec": "libx264", "label": "CPU (x264)", "extra": ["-preset", "medium", "-crf", "18"]}

    enc = ffmpeg_encoders()
    vendor = gpu_vendor()

    if "h264_amf" in enc and vendor in ("amd", ""):
        return {
            "codec": "h264_amf",
            "label": "AMD AMF (GPU)",
            "extra": ["-quality", "balanced", "-rc", "cqp", "-qp_i", "18", "-qp_p", "20"],
        }
    if "h264_nvenc" in enc and vendor == "nvidia":
        return {
            "codec": "h264_nvenc",
            "label": "NVENC (GPU)",
            "extra": ["-preset", "p5", "-cq", "20"],
        }
    if "h264_amf" in enc:
        return {
            "codec": "h264_amf",
            "label": "AMD AMF (GPU)",
            "extra": ["-quality", "balanced", "-rc", "cqp", "-qp_i", "18", "-qp_p", "20"],
        }
    if "h264_nvenc" in enc:
        return {
            "codec": "h264_nvenc",
            "label": "NVENC (GPU)",
            "extra": ["-preset", "p5", "-cq", "20"],
        }
    return {"codec": "libx264", "label": "CPU (x264)", "extra": ["-preset", "medium", "-crf", "18"]}


def gpu_encode_enabled() -> bool:
    try:
        from pathlib import Path
        import json

        root = Path(__file__).resolve().parents[1]
        for name in ("vidpuls-config.json", "jampulse-config.json"):
            p = root / "data" / name
            if p.is_file():
                cfg = json.loads(p.read_text(encoding="utf-8"))
                if cfg.get("gpu_encode") is False:
                    return False
                if cfg.get("gpu_render_24_7") or cfg.get("gpu_encode") is True:
                    return True
    except (json.JSONDecodeError, OSError):
        pass
    return True


def video_encoder(*, prefer_gpu: bool | None = None) -> dict:
    use_gpu = gpu_encode_enabled() if prefer_gpu is None else prefer_gpu
    return pick_video_encoder(prefer_gpu=use_gpu)


def ffmpeg_encode_args(*, crf_fallback: str = "18") -> list[str]:
    enc = video_encoder()
    if enc["codec"] == "libx264":
        return ["-c:v", "libx264", "-preset", "medium", "-crf", crf_fallback]
    return ["-c:v", enc["codec"], *enc["extra"]]


def render_status_label() -> str:
    enc = video_encoder()
    try:
        from jam.wan2gp_local import detect_gpu

        g = detect_gpu()
        name = g.get("name") or "GPU"
        vram = g.get("vram_gb") or 0
        vram_s = f" {int(vram)} GB" if vram else ""
        return f"{name}{vram_s} · {enc['label']}"
    except Exception:
        return enc["label"]
