"""Wan2GP Studio – lokale Web-UI für Jami-Prompts + LAN-Hilfe."""

from __future__ import annotations

import json
import webbrowser
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
from urllib.parse import urlparse

from jam.wan2gp_local import (
    STUDIO_PORT,
    _load_config,
    export_jami_prompt,
    local_ip,
    setup_wan2gp,
    wan2gp_dir,
    wan2gp_running,
)

ROOT = Path(__file__).resolve().parents[1]
STUDIO_ROOT = wan2gp_dir() / "Studio"
SITE_URL = f"http://127.0.0.1:{STUDIO_PORT}/"
PORT = STUDIO_PORT


def ensure_dirs() -> None:
    STUDIO_ROOT.mkdir(parents=True, exist_ok=True)


def _example_dialogue() -> str:
    from jam.ai_video_prompt import load_dialogue_text

    return load_dialogue_text(use_weekend_date=True)


def studio_html() -> str:
    cfg = _load_config()
    ip = local_ip()
    wport = cfg.get("wan2gp_port", 7860)
    script = cfg.get("pinokio_script", "wan2gp-amd")
    return f"""<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<title>Wan2GP Studio – VidPuls</title>
<style>
:root{{--bg:#07050f;--card:#12101f;--border:rgba(168,85,247,.35);--accent:#a855f7;--accent2:#ec4899;--text:#f1ecff;--muted:#9ca3af;--ok:#86efac;--warn:#fbbf24}}
*{{box-sizing:border-box}}
body{{margin:0;font-family:Segoe UI,system-ui,sans-serif;background:var(--bg);color:var(--text);min-height:100vh}}
.wrap{{max-width:960px;margin:0 auto;padding:1.5rem}}
h1{{margin:0 0 .25rem;font-size:1.75rem;background:linear-gradient(90deg,var(--accent),var(--accent2));-webkit-background-clip:text;-webkit-text-fill-color:transparent}}
.sub{{color:var(--muted);margin:0 0 1.25rem}}
.grid{{display:grid;grid-template-columns:1fr 1fr;gap:1rem}}
@media(max-width:800px){{.grid{{grid-template-columns:1fr}}}}
.card{{background:var(--card);border:1px solid var(--border);border-radius:16px;padding:1.25rem;margin-bottom:1rem}}
label{{display:block;font-size:.85rem;color:var(--muted);margin-bottom:.35rem}}
textarea{{width:100%;min-height:220px;background:#0c0a16;border:1px solid rgba(168,85,247,.25);border-radius:12px;color:var(--text);padding:1rem;font-size:.95rem;line-height:1.55;resize:vertical}}
textarea:focus{{outline:2px solid var(--accent)}}
.btn{{border:none;border-radius:10px;padding:.65rem 1rem;font-weight:600;cursor:pointer;font-size:.9rem}}
.btn-main{{width:100%;margin-top:.75rem;padding:1rem;font-size:1.05rem;background:linear-gradient(135deg,var(--accent),var(--accent2));color:#fff}}
.btn-sm{{background:#0c0a16;border:1px solid var(--border);color:var(--text)}}
.btn-sm:hover{{border-color:var(--accent)}}
.row{{display:flex;gap:.5rem;flex-wrap:wrap;margin-top:.5rem}}
.status{{padding:.75rem;border-radius:10px;background:#0c0a16;font-size:.88rem;margin-top:.75rem;color:var(--muted)}}
.status.on{{color:var(--ok);border:1px solid rgba(134,239,172,.3)}}
.status.off{{color:var(--warn);border:1px solid rgba(251,191,36,.3)}}
a{{color:var(--accent)}}
code{{background:#0c0a16;padding:.15rem .4rem;border-radius:5px;font-size:.85rem}}
ul{{color:var(--muted);line-height:1.7;padding-left:1.2rem}}
.prompt-out{{background:#0c0a16;border-radius:10px;padding:.85rem;font-size:.82rem;max-height:180px;overflow:auto;margin-top:.5rem;white-space:pre-wrap}}
.step{{display:flex;gap:.75rem;margin:.5rem 0;color:var(--muted);font-size:.9rem}}
.step b{{color:var(--text);min-width:1.5rem}}
</style>
</head>
<body>
<div class="wrap">
  <h1>Wan2GP Studio</h1>
  <p class="sub">Lokales KI-Video · 0 € Cloud · AMD RX 6900 XT · Pinokio <code>{script}</code></p>

  <div class="grid">
    <div class="card">
      <label for="dialog">Jami-Dialog (Sarah &amp; Laura)</label>
      <textarea id="dialog" placeholder="Sarah: …&#10;&#10;Laura: …"></textarea>
      <div class="row">
        <button type="button" class="btn btn-sm" id="loadEx">Beispiel laden</button>
        <button type="button" class="btn btn-sm" id="copyPrompt">Prompt kopieren</button>
      </div>
      <button type="button" class="btn btn-main" id="export">Prompt für Wan2GP exportieren</button>
      <div class="status" id="exportStatus">Bereit.</div>
      <div class="prompt-out" id="promptPreview" style="display:none"></div>
    </div>

    <div class="card">
      <label>Wan2GP Status</label>
      <div class="status off" id="wanStatus">Prüfe …</div>
      <p style="color:var(--muted);font-size:.88rem;margin:.75rem 0">
        <strong>Dieser PC:</strong> <a href="http://127.0.0.1:{wport}" target="_blank" id="wanLocal">http://127.0.0.1:{wport}</a><br/>
        <strong>WLAN (andere Geräte):</strong> <a href="http://{ip}:{wport}" target="_blank" id="wanLan">http://{ip}:{wport}</a>
      </p>
      <div class="row">
        <button type="button" class="btn btn-sm" id="openWan">Wan2GP öffnen</button>
        <button type="button" class="btn btn-sm" id="openPinokio">Pinokio Web</button>
      </div>
      <hr style="border-color:var(--border);margin:1rem 0"/>
      <p style="color:var(--muted);font-size:.85rem;margin:0 0 .5rem">Empfohlen für 16 GB VRAM:</p>
      <ul>
        <li><strong>{cfg.get('recommended_model')}</strong> – beste Qualität</li>
        <li><strong>{cfg.get('fast_model')}</strong> – schnell testen</li>
        <li>Format <strong>{cfg.get('aspect_ratio')}</strong> · {cfg.get('duration_sec')}s · {cfg.get('resolution')}</li>
      </ul>
    </div>
  </div>

  <div class="card">
    <label>Einrichtung (einmalig)</label>
    <div class="step"><b>1</b><span><a href="https://pinokio.computer" target="_blank">pinokio.computer</a> installieren</span></div>
    <div class="step"><b>2</b><span>Discover → <code>{script}</code> → Install (AMD: wan2gp-amd!)</span></div>
    <div class="step"><b>3</b><span>Launch Args: <code>{cfg.get('launch_args')}</code></span></div>
    <div class="step"><b>4</b><span>Prompt exportieren → in Wan2GP Text-to-Video einfügen</span></div>
    <div class="step"><b>5</b><span>Andere im WLAN: Link oben · Firewall: <code>Wan LAN freigeben.bat</code></span></div>
    <p style="color:var(--muted);font-size:.82rem;margin-top:.75rem">Anleitung: <code>Desktop\\VidPuls\\Wan2GP\\ANLEITUNG-WAN2GP.txt</code></p>
  </div>
</div>
<script>
const $ = (id) => document.getElementById(id);
let lastPrompt = "";

async function api(path, opts) {{
  const r = await fetch(path, opts);
  return r.json();
}}

async function refreshStatus() {{
  const h = await api("/api/health");
  const el = $("wanStatus");
  if (h.wan2gp_running) {{
    el.textContent = "Wan2GP läuft – bereit zum Generieren!";
    el.className = "status on";
  }} else {{
    el.textContent = "Wan2GP noch nicht gestartet – in Pinokio " + h.pinokio_script + " starten.";
    el.className = "status off";
  }}
}}

$("loadEx").onclick = async () => {{
  const d = await api("/api/dialogue");
  if (d.ok) $("dialog").value = d.text;
}};

$("export").onclick = async () => {{
  $("exportStatus").textContent = "Exportiere …";
  const data = await api("/api/export", {{
    method: "POST",
    headers: {{ "Content-Type": "application/json" }},
    body: JSON.stringify({{ dialogue: $("dialog").value }})
  }});
  if (data.ok) {{
    lastPrompt = data.prompt;
    $("exportStatus").textContent = "Gespeichert: " + data.path;
    $("promptPreview").style.display = "block";
    $("promptPreview").textContent = data.prompt;
  }} else {{
    $("exportStatus").textContent = data.error || "Fehler";
  }}
}};

$("copyPrompt").onclick = async () => {{
  if (!lastPrompt) {{
    await $("export").click();
  }}
  if (lastPrompt) {{
    await navigator.clipboard.writeText(lastPrompt);
    $("exportStatus").textContent = "Prompt in Zwischenablage kopiert!";
  }}
}};

$("openWan").onclick = () => window.open("http://127.0.0.1:{wport}", "_blank");
$("openPinokio").onclick = () => window.open("https://pinokio.computer", "_blank");

(async () => {{
  const d = await api("/api/dialogue");
  if (d.ok && !$("dialog").value.trim()) $("dialog").value = d.text;
  await refreshStatus();
  setInterval(refreshStatus, 5000);
}})();
</script>
</body>
</html>"""


class WanStudioHandler(SimpleHTTPRequestHandler):
    def log_message(self, fmt, *args):
        pass

    def _json(self, data, code=200):
        body = json.dumps(data, ensure_ascii=False).encode("utf-8")
        self.send_response(code)
        self.send_header("Content-Type", "application/json; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def _read_json(self) -> dict:
        n = int(self.headers.get("Content-Length") or 0)
        if n <= 0:
            return {}
        return json.loads(self.rfile.read(n).decode("utf-8"))

    def do_GET(self):
        path = urlparse(self.path).path
        if path == "/api/health":
            cfg = _load_config()
            return self._json({
                "ok": True,
                "wan2gp_running": wan2gp_running(),
                "pinokio_script": cfg.get("pinokio_script", "wan2gp-amd"),
                "lan_url": f"http://{local_ip()}:{cfg.get('wan2gp_port', 7860)}",
            })
        if path == "/api/dialogue":
            return self._json({"ok": True, "text": _example_dialogue()})
        if path in ("/", "/index.html"):
            body = studio_html().encode("utf-8")
            self.send_response(200)
            self.send_header("Content-Type", "text/html; charset=utf-8")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)
            return
        self.send_error(404)

    def do_POST(self):
        path = urlparse(self.path).path
        if path == "/api/export":
            body = self._read_json()
            dialogue = str(body.get("dialogue") or "")
            try:
                prompt, out = export_jami_prompt(
                    dialogue,
                    use_weekend_date=not dialogue.strip(),
                )
                return self._json({"ok": True, "prompt": prompt, "path": str(out)})
            except Exception as e:
                return self._json({"ok": False, "error": str(e)[:300]}, 500)
        return self._json({"ok": False, "error": "Unbekannt"}, 404)


def run_server(*, open_browser: bool = True) -> None:
    ensure_dirs()
    setup_wan2gp(firewall=False, export_prompt=True)
    httpd = ThreadingHTTPServer(("127.0.0.1", PORT), WanStudioHandler)
    print(f"Wan2GP Studio -> {SITE_URL}")
    print(f"Wan2GP Ziel:  http://127.0.0.1:{_load_config().get('wan2gp_port', 7860)}")
    if open_browser:
        webbrowser.open(SITE_URL, new=1)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\nBeendet.")
