@extends('layouts.overlay')

@section('title', 'DESKTOP')

@section('body-class', 'camera-hud-body')

@section('styles')
<style>
  :root {
    --cam-x: 1937px; --cam-y: 98px;  --cam-w: 549px;  --cam-h: 309px; --cam-pad: 10px;
    --scr-x: 10px;   --scr-y: 14px;  --scr-w: 1976px; --scr-h: 1209px; --scr-pad: 0px;
  }
  #signal { transform: translateY(-0.10em); }
</style>
@endsection

@section('crt')
{{-- transparent overlay — no CRT overlays --}}
@endsection

@section('content')
  @include('partials.screen-frame', ['id' => 'scr', 'label' => 'SCR 01'])
  @include('partials.camera-frame', ['id' => 'cam', 'label' => 'CAM 01'])

  <footer class="status-bar">
    <div class="status-line">
      <div class="live-block">
        <span class="live-dot"></span>
        <span>LIVE</span>
      </div>
      <span class="sep">·</span>
      <span class="scene-name">OPHI-118 // DESKTOP</span>
      <span class="spacer"></span>
      <span class="hud-tag"><span class="dim">SIGNAL</span><span id="signal" data-profile="normal">▮▮▮▯▯</span></span>
      <span class="sep">·</span>
      <span class="hud-tag"><span class="dim">UTC</span><span id="clock">--:--:--</span></span>
    </div>
    <div class="status-line meta-line">
      <span class="icon">◷</span>
      <span class="elapsed" id="elapsed">00:00:00</span>
      <span class="sep">·</span>
      <span class="icon" title="microphone">🎙</span>
      <span style="color: var(--term-fg);">ON</span>
    </div>
  </footer>
@endsection

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

  const streamStart = Date.now();
  function tickElapsed() {
    const s = Math.floor((Date.now() - streamStart) / 1000);
    const h = Math.floor(s / 3600);
    const mm = Math.floor((s / 60) % 60);
    const ss = s % 60;
    document.getElementById('elapsed').textContent = `${pad(h)}:${pad(mm)}:${pad(ss)}`;
  }
  tickElapsed(); setInterval(tickElapsed, 1000);

  const params       = new URLSearchParams(location.search);
  const CAM_SOURCE   = params.get('camera') || 'Camera';
  const SCR_SOURCE   = params.get('screen') || 'Screen Capture (PipeWire)';
  const SCENE_LOCK   = params.get('scene')  || null;

  const camEl    = document.getElementById('cam');
  const scrEl    = document.getElementById('scr');
  const rootStyle = document.documentElement.style;

  function renderedSize(t) {
    const useBounds = t.boundsType
                    && t.boundsType !== 'OBS_BOUNDS_NONE'
                    && (t.boundsWidth ?? 0) > 0;
    if (useBounds) return { w: t.boundsWidth, h: t.boundsHeight };
    return {
      w: (t.sourceWidth  ?? 0) * (t.scaleX ?? 1),
      h: (t.sourceHeight ?? 0) * (t.scaleY ?? 1),
    };
  }

  function makeFrame(obs, sourceName, frameEl, varPrefix) {
    const state = { sceneName: null, itemId: null };
    const setVisible = (v) => frameEl.classList.toggle('off', !v);
    const setTransform = (t) => {
      if (!t) return;
      const { w, h } = renderedSize(t);
      if (!(w > 0 && h > 0)) return;
      rootStyle.setProperty(`--${varPrefix}-x`, `${t.positionX}px`);
      rootStyle.setProperty(`--${varPrefix}-y`, `${t.positionY}px`);
      rootStyle.setProperty(`--${varPrefix}-w`, `${w}px`);
      rootStyle.setProperty(`--${varPrefix}-h`, `${h}px`);
    };
    return {
      async rebind(sceneName) {
        state.sceneName = sceneName;
        state.itemId    = null;
        if (!sceneName) { setVisible(false); return; }
        try {
          const r = await obs.call('GetSceneItemId', { sceneName, sourceName });
          state.itemId = r.sceneItemId;
          const e = await obs.call('GetSceneItemEnabled', { sceneName, sceneItemId: state.itemId });
          setVisible(e.sceneItemEnabled);
          const t = await obs.call('GetSceneItemTransform', { sceneName, sceneItemId: state.itemId });
          setTransform(t.sceneItemTransform);
        } catch {
          setVisible(false);
        }
      },
      handleEvent(d) {
        if (d.eventData?.sceneName    !== state.sceneName
         || d.eventData?.sceneItemId !== state.itemId) return;
        if (d.eventType === 'SceneItemEnableStateChanged') {
          setVisible(d.eventData.sceneItemEnabled);
        } else if (d.eventType === 'SceneItemTransformChanged') {
          setTransform(d.eventData.sceneItemTransform);
        }
      },
    };
  }

  OBSWSBootstrap.connect({
    onConnect: async (obs) => {
      const camFrame = makeFrame(obs, CAM_SOURCE, camEl, 'cam');
      const scrFrame = makeFrame(obs, SCR_SOURCE, scrEl, 'scr');
      let scene = SCENE_LOCK;
      if (!scene) {
        try {
          const r = await obs.call('GetCurrentProgramScene');
          scene = r.currentProgramSceneName || r.sceneName || null;
        } catch { /* leave null */ }
      }
      await Promise.all([camFrame.rebind(scene), scrFrame.rebind(scene)]);
      obs.addEventListener('event', async (ev) => {
        const d = ev.detail || {};
        if (!SCENE_LOCK && d.eventType === 'CurrentProgramSceneChanged') {
          const next = d.eventData?.sceneName;
          await Promise.all([camFrame.rebind(next), scrFrame.rebind(next)]);
          return;
        }
        camFrame.handleEvent(d);
        scrFrame.handleEvent(d);
      });
    },
  });
</script>
@endsection
