// ─────────────────────────────────────────────────────────────
//  admin/checkin.js — QR pass scanner for admin booking page
//
//  Requires jsQR loaded on the page:
//  <script src="https://cdnjs.cloudflare.com/ajax/libs/jsQR/1.4.0/jsQR.min.js"></script>
//
//  Exposes:
//    CheckinScanner.open()   — opens the modal, starts camera
//    CheckinScanner.close()  — stops camera, closes modal
// ─────────────────────────────────────────────────────────────

const CheckinScanner = (() => {
    // Derive app base from current URL — works regardless of install path.
    // e.g. https://example.com/app/admin.php → base = https://example.com/app
    const _base = window.location.pathname.replace(/\/admin(\.php|\/[^/]*)?$/, '').replace(/\/$/, '');
    const API = window.location.origin + _base + '/api/booking/checkin';
    let stream = null;
    let rafId  = null;
    let lastScan = 0; // debounce: ignore repeated scans within 3 s

    // ── DOM refs (injected by buildModal on first open) ───────
    let modal, video, canvas, ctx, statusEl, resultEl, manualInput, manualBtn;

    // ── Modal HTML ────────────────────────────────────────────
    function buildModal() {
        if (document.getElementById('checkin-modal')) return;

        const el = document.createElement('div');
        el.id = 'checkin-modal';
        el.style.cssText = `
            display:none;position:fixed;inset:0;z-index:9999;
            background:rgba(0,0,0,.72);align-items:center;justify-content:center;
        `;
        el.innerHTML = `
          <div style="background:var(--card,#161b27);border-radius:14px;padding:24px;
                      width:min(480px,94vw);box-shadow:0 24px 64px rgba(0,0,0,.5)">
            <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px">
              <span style="font-size:16px;font-weight:600;color:var(--text,#e2e8f0)">Scan Member Pass</span>
              <button onclick="CheckinScanner.close()" style="background:none;border:none;color:var(--muted,#64748b);
                font-size:20px;cursor:pointer;line-height:1;padding:0 4px">&times;</button>
            </div>

            <!-- Camera viewfinder -->
            <div style="position:relative;border-radius:10px;overflow:hidden;background:#000;aspect-ratio:1">
              <video id="checkin-video" playsinline autoplay muted
                     style="width:100%;height:100%;object-fit:cover;display:block"></video>
              <canvas id="checkin-canvas" style="display:none"></canvas>
              <!-- Aim guide -->
              <div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none">
                <div style="width:60%;aspect-ratio:1;border:2px solid rgba(2,172,237,.7);border-radius:8px;box-shadow:0 0 0 4000px rgba(0,0,0,.35)"></div>
              </div>
            </div>

            <div id="checkin-status" style="margin-top:12px;font-size:13px;color:var(--muted,#64748b);text-align:center;min-height:20px">
              Point camera at member's QR code
            </div>

            <!-- Result card (hidden until scan) -->
            <div id="checkin-result" style="display:none;margin-top:12px;border-radius:8px;padding:14px 16px;
                 background:var(--card-alt,#1e2535);border:1px solid var(--border,rgba(255,255,255,.08))">
            </div>

            <!-- Manual entry fallback -->
            <details style="margin-top:14px">
              <summary style="font-size:12px;color:var(--muted,#64748b);cursor:pointer;user-select:none">
                No camera? Enter token manually
              </summary>
              <div style="margin-top:8px;display:flex;gap:8px">
                <input id="checkin-manual" type="text" placeholder="Paste QR token here…"
                       style="flex:1;font-size:12px;padding:8px 10px;border-radius:6px;
                              background:var(--card,#161b27);border:1px solid var(--border,rgba(255,255,255,.1));
                              color:var(--text,#e2e8f0);outline:none"/>
                <button id="checkin-manual-btn"
                        style="padding:8px 14px;border-radius:6px;border:none;cursor:pointer;
                               background:var(--accent,#02aced);color:#fff;font-size:12px;font-weight:600">
                  Check in
                </button>
              </div>
            </details>
          </div>
        `;
        document.body.appendChild(el);

        modal       = el;
        video       = document.getElementById('checkin-video');
        canvas      = document.getElementById('checkin-canvas');
        ctx         = canvas.getContext('2d');
        statusEl    = document.getElementById('checkin-status');
        resultEl    = document.getElementById('checkin-result');
        manualInput = document.getElementById('checkin-manual');
        manualBtn   = document.getElementById('checkin-manual-btn');

        manualBtn.addEventListener('click', () => {
            const token = manualInput.value.trim();
            if (token) submitCheckin(token);
        });
        manualInput.addEventListener('keydown', e => {
            if (e.key === 'Enter') manualBtn.click();
        });
    }

    // ── Camera ────────────────────────────────────────────────
    async function startCamera() {
        statusEl.textContent = 'Starting camera…';
        try {
            stream = await navigator.mediaDevices.getUserMedia({
                video: { facingMode: 'environment', width: { ideal: 1280 } }
            });
            video.srcObject = stream;
            await video.play();
            statusEl.textContent = 'Point camera at member\'s QR code';
            rafId = requestAnimationFrame(scan);
        } catch (err) {
            statusEl.textContent = 'Camera unavailable — use manual entry below.';
            console.warn('Camera error:', err);
        }
    }

    function stopCamera() {
        if (rafId) { cancelAnimationFrame(rafId); rafId = null; }
        if (stream) { stream.getTracks().forEach(t => t.stop()); stream = null; }
        if (video)  { video.srcObject = null; }
    }

    // ── Scan loop ─────────────────────────────────────────────
    function scan() {
        if (!stream) return;
        if (video.readyState === video.HAVE_ENOUGH_DATA) {
            canvas.width  = video.videoWidth;
            canvas.height = video.videoHeight;
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
            const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
            const code = jsQR(imageData.data, imageData.width, imageData.height, {
                inversionAttempts: 'dontInvert',
            });
            if (code && Date.now() - lastScan > 3000) {
                lastScan = Date.now();
                submitCheckin(code.data);
            }
        }
        rafId = requestAnimationFrame(scan);
    }

    // ── API call ──────────────────────────────────────────────
    async function submitCheckin(token) {
        statusEl.textContent = 'Verifying…';
        resultEl.style.display = 'none';

        try {
            const res  = await fetch(API, {
                method:  'POST',
                headers: { 'Content-Type': 'application/json' },
                body:    JSON.stringify({ qr_payload: token }),
            });
            const data = await res.json();

            if (data.ok) {
                showResult(true, data);
                statusEl.textContent = '✓ Checked in successfully';
                // Flash viewfinder green briefly
                flashOverlay('#16a34a');
            } else {
                showResult(false, data);
                statusEl.textContent = data.error || 'Check-in failed';
                flashOverlay('#dc2626');
            }
        } catch (err) {
            statusEl.textContent = 'Network error — try again';
            console.error('Checkin API error:', err);
        }
    }

    function showResult(ok, data) {
        resultEl.style.display = 'block';
        if (ok) {
            const sess = data.sessions_remaining !== null
                ? `<span style="color:var(--accent,#02aced);font-weight:600">${data.sessions_remaining}</span> sessions remaining`
                : '<span style="color:#16a34a">Unlimited plan</span>';
            resultEl.innerHTML = `
              <div style="display:flex;align-items:center;gap:10px">
                <span style="font-size:22px">✅</span>
                <div>
                  <div style="font-weight:600;color:var(--text,#e2e8f0)">${esc(data.customer_name)}</div>
                  <div style="font-size:12px;color:var(--muted,#64748b)">${esc(data.customer_email)}</div>
                  <div style="font-size:12px;margin-top:4px">${sess}</div>
                </div>
              </div>`;
        } else {
            resultEl.innerHTML = `
              <div style="display:flex;align-items:center;gap:10px">
                <span style="font-size:22px">❌</span>
                <div style="color:#ef4444;font-weight:600">${esc(data.error || 'Check-in failed')}</div>
              </div>`;
        }
    }

    function flashOverlay(color) {
        const flash = document.createElement('div');
        flash.style.cssText = `position:absolute;inset:0;background:${color};opacity:.35;
            pointer-events:none;border-radius:10px;transition:opacity .6s`;
        video.parentElement.appendChild(flash);
        setTimeout(() => { flash.style.opacity = '0'; }, 100);
        setTimeout(() => flash.remove(), 800);
    }

    function esc(str) {
        return String(str ?? '').replace(/[&<>"']/g, c =>
            ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
    }

    // ── Public API ────────────────────────────────────────────
    return {
        open() {
            buildModal();
            modal.style.display = 'flex';
            lastScan = 0;
            resultEl.style.display = 'none';
            statusEl.textContent   = 'Starting camera…';
            startCamera();
        },
        close() {
            stopCamera();
            if (modal) modal.style.display = 'none';
        },
    };
})();
