"""Dialog Studio – GPU-Render-Server (24/7, Warteschlange, Status)."""

from __future__ import annotations

import time
from collections import deque
from datetime import datetime, timezone
from pathlib import Path
from threading import Lock

_queue_lock = Lock()
_job_queue: deque[str] = deque()
_server_started_at: float = 0.0


def mark_server_started() -> None:
    global _server_started_at
    _server_started_at = time.time()


def server_uptime_sec() -> float:
    if _server_started_at <= 0:
        return 0.0
    return max(0.0, time.time() - _server_started_at)


def gpu_info() -> dict:
    try:
        from jam.wan2gp_local import detect_gpu

        g = detect_gpu()
        enc = {}
        try:
            from jam.gpu_render import video_encoder

            enc = video_encoder()
        except ImportError:
            pass
        return {
            "name": str(g.get("name") or "GPU"),
            "vendor": str(g.get("vendor") or ""),
            "vram_gb": float(g.get("vram_gb") or 0),
            "encoder": str(enc.get("codec") or "libx264"),
            "encoder_label": str(enc.get("label") or "CPU"),
        }
    except Exception:
        return {"name": "GPU", "vendor": "", "vram_gb": 0.0, "encoder": "libx264", "encoder_label": "CPU"}


def queue_snapshot(*, active_job: str | None, jobs_dir: Path) -> dict:
    with _queue_lock:
        waiting = list(_job_queue)
    queued_meta: list[dict] = []
    for jid in waiting[:20]:
        p = jobs_dir / f"{jid}.json"
        if p.is_file():
            try:
                import json

                row = json.loads(p.read_text(encoding="utf-8"))
                queued_meta.append(
                    {
                        "id": jid,
                        "created_at": row.get("created_at", ""),
                        "status": row.get("status", "queued"),
                    }
                )
            except (OSError, json.JSONDecodeError):
                queued_meta.append({"id": jid, "status": "queued"})
    return {
        "active_job": active_job,
        "waiting_count": len(waiting),
        "waiting_ids": waiting,
        "waiting": queued_meta,
        "total_in_pipeline": len(waiting) + (1 if active_job else 0),
    }


def enqueue(job_id: str) -> int:
    """1-basierte Warteposition."""
    with _queue_lock:
        if job_id in _job_queue:
            return _job_queue.index(job_id) + 1
        _job_queue.append(job_id)
        return len(_job_queue)


def pop_next() -> str | None:
    with _queue_lock:
        if not _job_queue:
            return None
        return _job_queue.popleft()


def remove_from_queue(job_id: str) -> None:
    with _queue_lock:
        try:
            _job_queue.remove(job_id)
        except ValueError:
            pass


def server_status_public(*, active_job: str | None, jobs_dir: Path, port: int) -> dict:
    from jam.dialog_shop import STUDIO_PORT, pricing_public
    from jam.wan2gp_local import local_ip

    pr = pricing_public()
    gpu = gpu_info()
    enc = gpu.get("encoder_label") or "GPU"
    q = queue_snapshot(active_job=active_job, jobs_dir=jobs_dir)
    ip = local_ip()
    return {
        "ok": True,
        "online": True,
        "mode": "gpu_render_24_7",
        "gpu": gpu,
        "gpu_label": f"{gpu['name']} ({gpu['vram_gb']:.0f} GB)" if gpu.get("vram_gb") else gpu["name"],
        "gpu_encoder": enc,
        "gpu_label_full": f"{gpu['name']} · {enc}",
        "queue": q,
        "lan_url": pr.get("lan_url") or f"http://{ip}:{port}/",
        "local_url": pr.get("local_url") or f"http://127.0.0.1:{port}/",
        "uptime_sec": round(server_uptime_sec()),
        "message": "GPU-Server online – Kunden-Videos werden auf dieser Grafikkarte gerendert (3D + AMF).",
    }


def append_server_log(studio_root: Path, line: str) -> None:
    log = studio_root / "gpu-server.log"
    ts = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
    try:
        with log.open("a", encoding="utf-8") as f:
            f.write(f"[{ts}] {line}\n")
    except OSError:
        pass
