<?php
include('../config/db.php');
include('../includes/auth.php'); // BUG FIX: was missing — anyone could access scanner without login
include('partials/header.php'); ?>

<div class="pg-title">Scan QR Code</div>
<div class="pg-sub">Point camera at a customer's voucher QR to redeem it</div>

<div class="row justify-content-center g-4">

  <!-- Scanner card -->
  <div class="col-md-5 col-lg-4">
    <div class="adm-card" style="text-align:center;padding:24px">

      <!-- Camera access explainer — shown until camera starts -->
      <div id="https-warn" style="display:none;background:rgba(245,197,24,.08);border:1px solid rgba(245,197,24,.25);border-radius:8px;padding:14px;margin-bottom:16px;text-align:left;font-size:13px">
        <div style="font-weight:700;color:var(--yellow);margin-bottom:6px"><i class="bi bi-exclamation-triangle-fill"></i> Camera blocked</div>
        <p style="color:var(--muted);margin:0;line-height:1.6">
          Browsers <strong style="color:var(--text)">only allow camera access on HTTPS or localhost</strong>.
          If you're accessing this over a local IP (e.g. 192.168.x.x), do one of these:
        </p>
        <ul style="color:var(--muted);margin:10px 0 0 16px;line-height:2">
          <li>Use <strong style="color:var(--text)">localhost</strong> on the same machine, or</li>
          <li>Set up a free SSL cert with <strong style="color:var(--text)">mkcert</strong> for your local IP, or</li>
          <li>Use the <strong style="color:var(--text)">manual entry</strong> below instead</li>
        </ul>
      </div>

      <!-- Camera selector (shown when multiple cameras found) -->
      <div id="cam-select-wrap" style="display:none;margin-bottom:12px">
        <label class="frm-label" style="text-align:left;display:block">Select Camera</label>
        <select id="cam-select" class="frm-ctrl" onchange="switchCamera(this.value)"></select>
      </div>

      <div id="reader" style="border-radius:10px;overflow:hidden;width:100%;min-height:60px"></div>

      <div id="scan-msg" style="margin-top:14px;font-size:13.5px;color:var(--muted)">
        <i class="bi bi-camera"></i> Requesting camera…
      </div>

      <!-- Stop/restart button -->
      <button id="btn-stop" onclick="stopCamera()"
              style="display:none;margin-top:10px"
              class="btn-ghost">
        <i class="bi bi-stop-circle"></i> Stop Camera
      </button>
    </div>
  </div>

  <!-- Manual code entry fallback -->
  <div class="col-md-5 col-lg-4">
    <div class="adm-card">
      <div style="font-weight:700;font-size:14px;margin-bottom:4px">
        <i class="bi bi-keyboard" style="color:var(--accent);margin-right:6px"></i>Manual Entry
      </div>
      <div style="font-size:12.5px;color:var(--muted);margin-bottom:16px">
        Type or paste the voucher code if the camera is unavailable.
      </div>
      <form onsubmit="manualRedeem(event)">
        <label class="frm-label">Voucher Code <span style="font-size:11px;color:var(--muted);font-weight:400;text-transform:none">(or point physical scanner here)</span></label>
        <input type="text" id="manual-code" class="frm-ctrl"
               placeholder="ICE-XXXXXXXX"
               autocomplete="off" autocapitalize="characters"
               autofocus
               style="text-transform:uppercase;letter-spacing:2px;font-family:var(--mono);margin-bottom:12px"
               oninput="scannerAutoSubmit(this)">
        <button type="submit" id="manual-btn" class="btn-accent" style="width:100%">
          <i class="bi bi-check2-circle"></i> Redeem Voucher
        </button>
      </form>
      <div id="manual-msg" style="margin-top:12px;font-size:13px;display:none"></div>
    </div>
  </div>

</div>

<script src="https://unpkg.com/html5-qrcode@2.3.8/html5-qrcode.min.js"></script>
<script>
let qrScanner = null;
let currentCamId = null;
let scanLocked = false;

// ── Boot ───────────────────────────────────────────────────────────────────────
(async function init() {
  // Detect if we're on an insecure non-localhost origin — camera won't work
  const isSecure = location.protocol === 'https:'
    || location.hostname === 'localhost'
    || location.hostname === '127.0.0.1'
    || location.hostname === '[::1]';

  if (!isSecure) {
    document.getElementById('https-warn').style.display = 'block';
    setMsg('<i class="bi bi-lock" style="color:var(--yellow)"></i> Camera unavailable on plain HTTP — use manual entry below', '');
    return;
  }

  // Check MediaDevices API availability
  if (!navigator.mediaDevices?.getUserMedia) {
    setMsg('<i class="bi bi-exclamation-triangle-fill" style="color:var(--red)"></i> Camera API not supported in this browser', '');
    return;
  }

  try {
    const devices = await Html5Qrcode.getCameras();

    if (!devices || devices.length === 0) {
      setMsg('<i class="bi bi-camera-video-off" style="color:var(--red)"></i> No camera found', '');
      return;
    }

    // Populate camera selector if more than one camera
    if (devices.length > 1) {
      const sel = document.getElementById('cam-select');
      devices.forEach(d => {
        const opt = document.createElement('option');
        opt.value = d.id; opt.textContent = d.label || `Camera ${d.id}`;
        sel.appendChild(opt);
      });
      document.getElementById('cam-select-wrap').style.display = 'block';
    }

    // Prefer back camera on mobile
    const backCam = devices.find(d => /back|rear|environment/i.test(d.label));
    currentCamId = backCam ? backCam.id : devices[0].id;
    if (document.getElementById('cam-select').options.length > 0)
      document.getElementById('cam-select').value = currentCamId;

    startCamera(currentCamId);

  } catch (err) {
    document.getElementById('https-warn').style.display = 'block';
    setMsg('<i class="bi bi-exclamation-triangle-fill" style="color:var(--red)"></i> Camera access denied — see note above', '');
  }
})();

// ── Start scanner ──────────────────────────────────────────────────────────────
function startCamera(camId) {
  scanLocked = false;
  qrScanner = new Html5Qrcode('reader');
  qrScanner.start(
    camId,
    { fps: 10, qrbox: { width: 240, height: 240 } },
    async code => {
      if (scanLocked) return;
      scanLocked = true;
      await stopScannerSilently();
      setMsg('<i class="bi bi-check-circle-fill" style="color:var(--green)"></i> QR detected — loading…', '');
      document.getElementById('btn-stop').style.display = 'none';

      // Extract just the code whether QR contains a full URL or just the code
      let voucherCode = code;
      let claimId = '';
      try {
        const url = new URL(code);
        const param = url.searchParams.get('code');
        claimId = url.searchParams.get('claim_id') || '';
        if (param) voucherCode = param;
      } catch(e) {
        // Not a URL — use raw value as the code
      }

      redeemScannedCode(voucherCode, claimId);
    },
    () => {}
  ).then(() => {
    setMsg('<i class="bi bi-camera-video-fill" style="color:var(--green)"></i> Camera active — scan a voucher', '');
    document.getElementById('btn-stop').style.display = 'inline-flex';
  }).catch(err => {
    document.getElementById('https-warn').style.display = 'block';
    setMsg('<i class="bi bi-exclamation-triangle-fill" style="color:var(--red)"></i> Could not start camera: ' + err, '');
  });
}

async function stopScannerSilently() {
  if (!qrScanner) return;
  try { await qrScanner.stop(); } catch(e) {}
  try { await qrScanner.clear(); } catch(e) {}
  qrScanner = null;
}

function stopCamera() {
  stopScannerSilently();
  document.getElementById('btn-stop').style.display = 'none';
  setMsg('<i class="bi bi-camera"></i> Camera stopped', '');
}

function switchCamera(camId) {
  stopCamera();
  setTimeout(() => startCamera(camId), 400);
}

function setMsg(html) {
  document.getElementById('scan-msg').innerHTML = html;
}

function restartScannerSoon(delay = 1400) {
  setTimeout(() => {
    if (!currentCamId) return;
    setMsg('<i class="bi bi-camera"></i> Ready for next voucher...');
    startCamera(currentCamId);
  }, delay);
}

function redeemScannedCode(code, claimId = '') {
  fetch('redeem.php', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-Token': CSRF },
    body: 'mode=redeem&code=' + encodeURIComponent(code) + '&claim_id=' + encodeURIComponent(claimId || '')
  })
  .then(r => r.json())
  .then(d => {
    const ok = d.status === 'success';
    const heading = d.heading || d.error || 'Could not redeem';
    const sub = d.sub || '';
    const color = ok ? 'var(--green)' : 'var(--red)';
    const icon  = ok ? 'check-circle-fill' : 'x-circle-fill';
    setMsg(`
      <div style="background:${ok?'rgba(45,189,135,.08)':'rgba(224,82,82,.08)'};border:1px solid ${color}33;border-radius:10px;padding:14px 16px;text-align:center">
        <div style="font-size:28px;color:${color};margin-bottom:6px"><i class="bi bi-${icon}"></i></div>
        <div style="font-weight:700;font-size:14px;color:${color}">${heading}</div>
        <div style="font-size:12px;color:var(--muted);margin-top:4px">${sub}</div>
        ${d.code ? `<div style="font-family:var(--mono);font-size:11px;background:var(--bg);padding:4px 10px;border-radius:6px;color:var(--accent);display:inline-block;margin-top:8px">${d.code}</div>` : ''}
      </div>`);
    showToast(ok ? 'Voucher redeemed. Scanner readying next.' : heading, ok ? 'success' : 'error');
    restartScannerSoon(ok ? 1200 : 2200);
  })
  .catch(() => {
    setMsg('<span style="color:var(--red)"><i class="bi bi-exclamation-triangle-fill"></i> Network error - scanner restarting</span>');
    restartScannerSoon(2200);
  });
}

// ── Manual entry ───────────────────────────────────────────────────────────────
// Physical scanner auto-submit — scanners type very fast then send Enter
// We detect rapid input (>4 chars in <100ms) and auto-submit
let scannerTimer = null;
let scannerLastLen = 0;
let scannerStartTime = 0;
function scannerAutoSubmit(input) {
  const now = Date.now();
  const val = input.value;
  if (val.length === 1) { scannerStartTime = now; scannerLastLen = 1; return; }
  const elapsed = now - scannerStartTime;
  const chars = val.length - scannerLastLen;
  scannerLastLen = val.length;
  // If 4+ chars typed in under 80ms — it's a scanner, not a human
  if (val.length >= 6 && elapsed < 400 && chars > 2) {
    clearTimeout(scannerTimer);
    scannerTimer = setTimeout(() => {
      if (document.getElementById('manual-code').value.trim().length >= 6) {
        document.getElementById('manual-btn').click();
      }
    }, 120);
  }
}

function manualRedeem(e) {
  e.preventDefault();
  let code = document.getElementById('manual-code').value.trim();
  let claimId = '';
  try {
    const url = new URL(code);
    const param = url.searchParams.get('code');
    claimId = url.searchParams.get('claim_id') || '';
    if (param) code = param;
  } catch(e) {}
  code = code.toUpperCase();
  if (!code) return;
  const msg = document.getElementById('manual-msg');
  const btn = document.getElementById('manual-btn');
  msg.style.display = 'block';
  msg.innerHTML = '<span style="color:var(--accent)"><i class="bi bi-hourglass-split"></i> Checking <strong>' + code + '</strong>…</span>';
  btn.disabled = true;

  fetch('redeem.php', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-Token': CSRF },
    body: 'mode=redeem&code=' + encodeURIComponent(code) + '&claim_id=' + encodeURIComponent(claimId)
  })
  .then(r => r.json())
  .then(d => {
    const ok = d.status === 'success';
    const color = ok ? 'var(--green)' : 'var(--red)';
    const icon  = ok ? 'check-circle-fill' : 'x-circle-fill';
    msg.innerHTML = `
      <div style="background:${ok?'rgba(45,189,135,.08)':'rgba(224,82,82,.08)'};border:1px solid ${color}33;border-radius:10px;padding:14px 16px;text-align:center">
        <div style="font-size:28px;color:${color};margin-bottom:6px"><i class="bi bi-${icon}"></i></div>
        <div style="font-weight:700;font-size:14px;color:${color}">${d.heading}</div>
        <div style="font-size:12px;color:var(--muted);margin-top:4px">${d.sub}</div>
        ${d.code ? `<div style="font-family:var(--mono);font-size:11px;background:var(--bg);padding:4px 10px;border-radius:6px;color:var(--accent);display:inline-block;margin-top:8px">${d.code}</div>` : ''}
      </div>`;
    if (ok) {
      document.getElementById('manual-code').value = '';
      showToast('Voucher redeemed: ' + code, 'success');
    }
  })
  .catch(() => {
    msg.innerHTML = '<span style="color:var(--red)"><i class="bi bi-exclamation-triangle-fill"></i> Network error — try again</span>';
  })
  .finally(() => { btn.disabled = false; });
}
</script>

<?php include('partials/footer.php'); ?>
