@extends('layouts.overlay')

@section('title', 'MUSIC BOX')

@section('styles')
<style>
  body.overlay-body {
    display: grid;
    grid-template-rows: auto 1fr auto auto auto;
    gap: 22px;
  }
  .stage {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .terminal {
    width: 64vw;
    max-width: 1480px;
    height: 60vh;
    max-height: 760px;
    min-height: 420px;
    font-size: 24px;
  }
</style>
@endsection

@push('data-scripts')
<script>window.__TRACK_COUNT = @json($trackCount);</script>
@endpush

@section('content')
  @include('partials.hud-strip', [
    'variant' => 'onair',
    'label'   => 'ON AIR',
    'idText'  => 'OPHI-118 // MUSIC',
    'signalGlyph' => '▮▮▮▮▯',
    'signalProfile' => 'strong',
  ])

  <main class="stage">
    <div class="terminal">
      <div id="termOutput"><div id="pinnedBlock"><div class="pin-spacer"></div><div class="term-line next-line"><span class="next-arrow">↳</span><span class="next-label">next:</span><span class="next-title empty" data-slot="0">— end of queue —</span></div><div class="term-line next-line"><span class="next-arrow">↳</span><span class="next-label">then:</span><span class="next-title empty" data-slot="1">—</span></div><div class="term-line next-line"><span class="next-arrow">↳</span><span class="next-label">then:</span><span class="next-title empty" data-slot="2">—</span></div><div class="pin-spacer"></div><div class="term-line np-line"><span class="np-arrow">▶</span><span class="np-title">connecting to daemon…</span><span class="np-time">[--:-- / --:--]</span></div></div></div>
    </div>
  </main>

  <section class="status-strip">
    <span class="label">CHAT</span>
    <span class="cmd-group">
      <span><span class="cmd">!skip</span><span class="desc">next track</span></span>
      <span><span class="cmd">!queue</span><span class="desc">peek next 3</span></span>
      <span><span class="cmd">!info</span><span class="desc">full metadata</span></span>
    </span>
  </section>

  <section class="banner banner--green">
    <div class="label">— TRANSMISSION OPEN —</div>
    <div class="title">MUSIC&nbsp;BOX</div>
    <div class="sub">— STAY TUNED —</div>
  </section>

  <footer class="foot">
    <span>CH 118.0 MHz</span>
    <span id="rig">— LOADING PLAYLIST —</span>
    <span class="onair">■ ON AIR</span>
  </footer>
@endsection

@section('scripts')
<script>
  'use strict';
  const pad = HUD.pad;

  const trackCount = window.__TRACK_COUNT || 0;
  document.getElementById('rig').textContent =
    trackCount > 0 ? `LIBRARY :: ${trackCount} TRACKS` : '— EMPTY LIBRARY —';

  const sleep = ms => new Promise(r => setTimeout(r, ms));
  const term        = document.getElementById('termOutput');
  const pinnedBlock = document.getElementById('pinnedBlock');
  const npTitle     = pinnedBlock.querySelector('.np-title');
  const npTime      = pinnedBlock.querySelector('.np-time');
  const nextSlots   = [0, 1, 2].map(i => pinnedBlock.querySelector(`[data-slot="${i}"]`));
  const PROMPT      = 'OPHI-118://> ';
  const MAX_TERM_LINES = 200;

  function pruneTerminal() {
    while (term.children.length > MAX_TERM_LINES) {
      const first = term.firstElementChild;
      if (!first || first === pinnedBlock) break;
      term.removeChild(first);
    }
    while (term.children.length > 1) {
      let total = 0;
      for (const c of term.children) total += c.getBoundingClientRect().height;
      if (total <= term.clientHeight) break;
      const first = term.firstElementChild;
      if (!first || first === pinnedBlock) break;
      term.removeChild(first);
    }
  }
  function logBeforePins(text, cls = 'term-out', prompt = '> ') {
    const div = document.createElement('div');
    div.className = 'term-line';
    if (prompt) {
      const p = document.createElement('span');
      p.className = 'term-prompt';
      p.textContent = prompt;
      div.appendChild(p);
    }
    const t = document.createElement('span');
    if (cls) t.className = cls;
    t.textContent = text;
    div.appendChild(t);
    term.insertBefore(div, pinnedBlock);
    pruneTerminal();
  }
  async function typeCommand(text) {
    const div = document.createElement('div');
    div.className = 'term-line';
    const p = document.createElement('span');
    p.className = 'term-prompt';
    p.textContent = PROMPT;
    div.appendChild(p);
    const body = document.createElement('span');
    body.className = 'term-out';
    div.appendChild(body);
    term.insertBefore(div, pinnedBlock);
    for (const c of text) {
      body.textContent += c;
      await sleep(38);
    }
    await sleep(280);
  }
  function fmtClock(s) {
    if (!isFinite(s) || s < 0) return '--:--';
    return `${pad(Math.floor(s / 60))}:${pad(Math.floor(s % 60))}`;
  }

  let lastTrackFile = null;
  function applyState(s) {
    if (lastTrackFile !== null && s.file && s.file !== lastTrackFile && s.title) {
      logBeforePins(`[audio] now: ${s.title}`);
    }
    if (s.file) lastTrackFile = s.file;
    npTitle.textContent = s.title || '—';
    npTime.textContent  = `[${fmtClock(s.currentTime)} / ${fmtClock(s.duration)}]`;
    const titles = Array.isArray(s.nextTitles) ? s.nextTitles : [];
    nextSlots.forEach((slot, i) => {
      const v = titles[i];
      if (v) {
        slot.textContent = v;
        slot.classList.remove('empty');
      } else {
        slot.textContent = i === 0 ? '— end of queue —' : '—';
        slot.classList.add('empty');
      }
    });
    pruneTerminal();
  }
  function setOffline(msg) {
    npTitle.textContent = msg;
    npTime.textContent  = '[--:-- / --:--]';
  }

  function startMusic() {
    OBSWSBootstrap.onState(applyState, {
      onClose: () => {
        logBeforePins('[audio] daemon connection lost — retrying', 'term-dim');
        setOffline('daemon disconnected');
      },
    });
  }

  (async () => {
    await sleep(450);
    await typeCommand('music --boot --shuffle');
    logBeforePins('[audio] subscribing to mpd:state events', 'term-out');
    await sleep(220);
    if (trackCount > 0) {
      logBeforePins(`[audio] library: ${trackCount} tracks`, 'term-out');
    } else {
      logBeforePins('[audio] library manifest empty', 'term-dim');
    }
    await sleep(180);
    logBeforePins('[audio] queue: shuffle on', 'term-out');
    await sleep(180);
    logBeforePins('[audio] standby for transmission ✓', 'term-out');
    await sleep(280);
    startMusic();
  })();
</script>
@endsection
