[Back]
@extends('layout')

@section('title')
  <title>Scan QR</title>
@endsection

@section('content')
<section class="container py-4">
  <h1 class="h4 mb-2">Scan Checkpoint QR</h1>
  <p class="text-muted mb-3">
    Point your camera at the QR on the sign. Voice guidance will play automatically after we update your location.
  </p>

  <div id="reader" style="width:100%; max-width:520px; aspect-ratio: 1 / 1; background:#f8f9fa; border-radius:12px; position: relative; overflow: hidden;"></div>

  <div id="scan-status" class="small text-muted mt-2"></div>

  <div class="mt-3 d-flex gap-2">
    <a href="{{ url()->previous() ?: route('map.show','floor1') }}" class="btn btn-outline-secondary">Back</a>
  </div>
</section>

<script src="{{ asset('vendor/html5-qrcode/html5-qrcode.min.js') }}"></script>

<script>
(function() {
  const statusEl = document.getElementById('scan-status');
  const readerId = 'reader';
  const LS_KEY_CAMERA = 'qr_preferred_camera_id';

  function setStatus(msg, isErr=false) {
    statusEl.textContent = msg || '';
    statusEl.classList.toggle('text-danger', !!isErr);
  }

  // Secure-origin check (required by getUserMedia)
  const isSecure = location.protocol === 'https:' || location.hostname === 'localhost' || location.hostname === '127.0.0.1';
  if (!isSecure) {
    setStatus('Camera requires HTTPS or http://localhost. Open this as http://localhost:8000 or use HTTPS (Valet/ngrok).', true);
    return;
  }

  if (!navigator.mediaDevices?.getUserMedia) {
    setStatus('This browser does not support camera access (getUserMedia). Try a modern browser.', true);
    return;
  }

  // Redirect helper
  function go(url) {
    sessionStorage.setItem('map_voice_unlocked', '1');
    localStorage.setItem('map_voice_enabled', '1');
    try {
      const u = new URL(url, window.location.origin);
      if (!u.searchParams.has('s')) u.searchParams.set('s','1');
      window.location.href = u.toString();
    } catch { window.location.href = url; }
  }

  // Decode handler
  function onScanSuccess(text) {
    // Stop the scanner once we got a code (prevents double redirects)
    try { html5Scanner?.clear(); } catch {}
    try { html5Instance?.stop().then(()=>{}); } catch {}
    // Full URL or slug support
    try { const u = new URL(text); go(u.toString()); return; } catch {}
    let path = text.trim();
    if (/^https?:/i.test(path)) { go(path); return; }
    const [slugPart, queryPart] = path.split('?');
    let url = new URL("{{ route('nav.qr', ['slug'=>'__SLUG__']) }}".replace('__SLUG__',''));
    url.pathname += encodeURIComponent(slugPart);
    if (queryPart) {
      for (const kv of queryPart.split('&')) {
        const [k,v] = kv.split('=');
        if (k) url.searchParams.set(k, v ?? '');
      }
    }
    url.searchParams.set('s','1');
    go(url.toString());
  }
  function onScanFailure(_err) { /* per-frame decode errors are normal */ }

  let html5Scanner = null; // Html5QrcodeScanner UI
  let html5Instance = null; // Html5Qrcode direct instance (for cameraId fast start)

  // Overlay button shown only when we NEED a user gesture
  function showStartOverlay(startFn) {
    const host = document.getElementById(readerId);
    const overlay = document.createElement('button');
    overlay.type = 'button';
    overlay.className = 'btn btn-primary';
    overlay.textContent = 'Start scanner';
    Object.assign(overlay.style, {
      position: 'absolute', inset: '0',
      width: '100%', height: '100%',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontSize: '1.1rem',
      border: 'none',
      borderRadius: getComputedStyle(host).borderRadius || '12px',
      background: 'rgba(0,123,255,0.95)',
      color: '#fff'
    });
    overlay.addEventListener('click', async () => {
      overlay.remove();
      await startFn();
    }, { once: true });
    host.appendChild(overlay);
  }

  async function startScannerUi() {
    setStatus('Starting scanner…');
    html5Scanner = new Html5QrcodeScanner(readerId, {
      fps: 10,
      qrbox: 300,
      rememberLastUsedCamera: true
    }, false);
    html5Scanner.render(onScanSuccess, onScanFailure);
    setTimeout(() => {
      if (!document.querySelector('#' + readerId + ' video')) {
        setStatus('If you don’t see the camera prompt, allow camera access in the browser/site settings and reload.', true);
      } else {
        setStatus('');
      }
    }, 1200);
  }

  async function startScannerFast(cameraId) {
    // Start directly with a specific deviceId (fastest path, no UI chrome)
    setStatus('Starting camera…');
    html5Instance = new Html5Qrcode(readerId);
    try {
      await html5Instance.start(
        cameraId,
        { fps: 10, qrbox: 300, aspectRatio: 1.0 },
        onScanSuccess,
        onScanFailure
      );
      setStatus('');
    } catch (e) {
      // Fallback to UI if deviceId fails (device unplugged/renamed)
      try { await html5Instance.clear(); } catch {}
      html5Instance = null;
      await startScannerUi();
    }
  }

  async function pickPreferredOrEnvAndStart() {
    // If we stored a cameraId, try that first for instant start
    const savedId = localStorage.getItem(LS_KEY_CAMERA);
    try {
      const cameras = await Html5Qrcode.getCameras();
      if (cameras?.length) {
        // Prefer saved device; else prefer environment/back
        const env = cameras.find(c => /back|rear|environment/i.test(c.label)) || cameras[0];
        const chosen = cameras.find(c => c.id === savedId) || env;
        localStorage.setItem(LS_KEY_CAMERA, chosen.id); // store for next time
        return startScannerFast(chosen.id);
      }
    } catch (_) {
      // If listing cameras fails (permissions), fall back to UI (it will prompt)
    }
    return startScannerUi();
  }

  // After user uses the UI once, capture the deviceId and remember it
  window.addEventListener('cameraSelection', async (ev) => {
    // Some browsers dispatch a devicechange; html5-qrcode doesn’t emit a public event.
    // We’ll also try to read the active device after UI starts:
    try {
      const cams = await Html5Qrcode.getCameras();
      const env = cams.find(c => /back|rear|environment/i.test(c.label)) || cams[0];
      if (env) localStorage.setItem(LS_KEY_CAMERA, env.id);
    } catch {}
  });

  // === Permission strategy ===
  (async () => {
    // If permission already granted → auto-start with preferred/env camera (no prompt)
    try {
      const perm = await (navigator.permissions?.query({ name: 'camera' }) ?? Promise.reject());
      if (perm.state === 'granted') {
        pickPreferredOrEnvAndStart();
        return;
      }
      if (perm.state === 'prompt') {
        // We need a user gesture; show one big button
        showStartOverlay(() => startScannerUi());
        setStatus('Tap “Start scanner” to allow camera.');
        return;
      }
      // denied
      setStatus('Camera permission is blocked. Enable it in your browser/site settings, then reload.', true);
      return;
    } catch {
      // Permissions API not available (iOS older Safari). Try fast path; if it needs a gesture, show overlay.
      try {
        await pickPreferredOrEnvAndStart();
      } catch {
        showStartOverlay(() => startScannerUi());
        setStatus('Tap “Start scanner” to allow camera.');
      }
    }
  })();

})();
</script>

<style>
/* Make the reader container responsive while keeping max-width */
#reader {
  display: block;
  width: 100%;
  max-width: 520px;
  aspect-ratio: 1 / 1;
  background: #f8f9fa;
  border-radius: 12px;
  position: relative;
  overflow: hidden;
}

/* Force the injected video / canvas to fully cover the reader */
#reader video,
#reader canvas,
#reader .html5-qrcode-video,
#reader .html5-qrcode-canvas {
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
}

/* Some internal wrappers the library creates — ensure they don't limit size */
#reader .html5-qrcode-placeholder,
#reader .html5-qrcode-root,
#reader .html5-qrcode-region {
  width: 100% !important;
  height: 100% !important;
}

/* Keep overlay/start button full size and visible on small screens */
#reader > button,
#reader .btn {
  width: 100%;
  height: 100%;
  font-size: 1.05rem;
  border-radius: 12px;
}

/* Small-screen tweak */
@media (max-width: 576px) {
  #reader .btn { font-size: 1rem; }
}
</style>
@endsection