<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>OPHI-118 / Music Daemon</title>
<style>
  /* Diagnostic status page. Music is actually played by MPD (system service)
     and broadcast over OBS WS by bridges/mpd-state.py. This page no longer
     plays audio or broadcasts mpd:state — those would conflict with the
     bridge. It only listens to incoming mpd:state events so you can sanity-
     check the bridge from a single browser source. */
  html, body { margin: 0; padding: 0; background: #0a0e0a; overflow: hidden; color: #5fdc62;
                font: 14px/1.45 'DejaVu Sans Mono', 'Consolas', monospace; }
  #status     { padding: 12px 14px; }
  #status h1  { font-size: 11px; letter-spacing: 0.25em; color: #2c8d2f; margin: 0 0 8px; font-weight: 700; }
  #status .row { display: flex; gap: 10px; margin: 2px 0; }
  #status .k  { color: #2c8d2f; min-width: 70px; }
  #status .v  { color: #97f99a; word-break: break-all; }
  #status .err { color: #ff6f5a; }
  #status .ok  { color: #97f99a; }
  #status .dim { color: #2c8d2f; }
</style>
</head>
<body>

<div id="status">
  <h1>OPHI MUSIC DAEMON (passive)</h1>
  <div class="row"><span class="k">role</span><span class="v dim">listener — playback handled by mpd + bridges/mpd-state.py</span></div>
  <div class="row"><span class="k">ws</span><span class="v" id="s-ws">init…</span></div>
  <div class="row"><span class="k">now</span><span class="v" id="s-now">—</span></div>
  <div class="row"><span class="k">queue</span><span class="v" id="s-queue">—</span></div>
  <div class="row"><span class="k">elapsed</span><span class="v" id="s-elapsed">—</span></div>
  <div class="row"><span class="k">last cmd</span><span class="v" id="s-cmd">—</span></div>
</div>

@include('partials.obs-ws-scripts')

<script>
  'use strict';

  const $ws     = document.getElementById('s-ws');
  const $now    = document.getElementById('s-now');
  const $queue  = document.getElementById('s-queue');
  const $elapsed = document.getElementById('s-elapsed');
  const $cmd    = document.getElementById('s-cmd');
  const pad = n => String(n).padStart(2, '0');
  const fmtClock = s => (!isFinite(s) || s < 0)
    ? '--:--' : `${pad(Math.floor(s / 60))}:${pad(Math.floor(s % 60))}`;

  function setWs(text, cls = '') { $ws.textContent = text; $ws.className = 'v ' + cls; }

  let obs = null;
  async function connectOBS() {
    if (!window.__OBSWS) {
      setWs('public/js/obs-config.js MISSING — run `php artisan rig:setup`', 'err');
      return;
    }
    try {
      setWs(`connecting → ${window.__OBSWS.url}`);
      obs = new OBSWSMini(window.__OBSWS.url, window.__OBSWS.password);
      await obs.connect();
      setWs('identified ✓', 'ok');
      obs.addEventListener('close', () => {
        setWs('closed — retrying in 2s', 'err');
        setTimeout(connectOBS, 2000);
      });
      obs.onCustom('mpd:state', (s) => {
        $now.textContent = s.title ? `${s.title}${s.artist ? ` — ${s.artist}` : ''}` : '—';
        const total = Number(s.total) || 0;
        const idx   = Number.isInteger(s.index) ? s.index : -1;
        $queue.textContent = (total > 0 && idx >= 0)
          ? `${idx + 1} / ${total}${s.paused ? '  (paused)' : ''}`
          : '—';
        $elapsed.textContent = `${fmtClock(s.currentTime)} / ${fmtClock(s.duration)}`;
      });
      obs.onCustom('mpd:cmd', (d) => {
        $cmd.textContent = `${d.type || '?'} @ ${new Date().toLocaleTimeString()}`;
      });
    } catch (e) {
      setWs(`connect failed (${e.message}) — retrying`, 'err');
      setTimeout(connectOBS, 2500);
    }
  }
  connectOBS();
</script>
</body>
</html>
