(() => {
    document.addEventListener('DOMContentLoaded', () => {
        const scanForm = document.querySelector('[data-scan-form]');
        if (scanForm) {
            const endpoint = scanForm.dataset.endpoint;
            const qrInput = scanForm.querySelector('input[name="qr_token"]');
            const resultBox = document.querySelector('#scan-result');
            const statusBox = document.querySelector('#scan-status');
            const submitBtn = scanForm.querySelector('button[type="submit"]');
            const setStatus = (message, classes = 'text-white fw-semibold') => {
                if (!statusBox) return;
                statusBox.textContent = message;
                statusBox.className = classes;
            };

            scanForm.addEventListener('submit', async (event) => {
                event.preventDefault();
                if (!endpoint) return;

                const payload = Object.fromEntries(new FormData(scanForm));
                submitBtn.disabled = true;
                setStatus('Processing scan…');

                try {
                    const response = await fetch(endpoint, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'X-Requested-With': 'XMLHttpRequest'
                        },
                        body: JSON.stringify(payload)
                    });

                    const data = await response.json();
                    setStatus(
                        data.message || 'No response message',
                        data.success ? 'text-success fw-semibold' : 'text-danger fw-semibold'
                    );

                    if (data.meta && resultBox) {
                        resultBox.innerHTML = `
                            <div class="list-group">
                                <div class="list-group-item">
                                    <strong>Student:</strong> ${data.meta.student ?? '—'}
                                </div>
                                <div class="list-group-item">
                                    <strong>Activity:</strong> ${data.meta.activity ?? '—'}
                                </div>
                                <div class="list-group-item">
                                    <strong>Action:</strong> ${data.meta.action ?? '—'}
                                </div>
                                <div class="list-group-item">
                                    <strong>Recorded:</strong> ${data.meta.timestamp ?? '—'}
                                </div>
                            </div>
                        `;
                    }

                    qrInput.value = '';
                    qrInput.focus();
                } catch (error) {
                    console.error(error);
                    setStatus('Unable to process scan. Please try again.', 'text-danger fw-semibold');
                } finally {
                    submitBtn.disabled = false;
                }
            });

            setupCameraScanner(scanForm, qrInput, setStatus);
        }
    });

    function setupCameraScanner(form, qrInput, setStatus) {
        const cameraRegion = document.querySelector('#camera-viewer');
        const startButton = document.querySelector('[data-scan-start]');
        if (!cameraRegion || !startButton) return;

        let html5Scanner = null;
        let fallbackController = null;

        startButton.addEventListener('click', async () => {
            if (startButton.dataset.state === 'running') {
                await stopScanner();
                return;
            }

            startButton.disabled = true;
            setStatus('Initializing camera scanner…');
            const started = await startScanner();
            startButton.disabled = false;

            if (!started) {
                startButton.classList.add('disabled');
                cameraRegion.innerHTML = '<div class="text-danger text-center small">Camera scan unavailable in this browser.</div>';
                setStatus('Camera scan unavailable. Please type QR token manually.', 'text-warning fw-semibold');
            }
        });

        async function startScanner() {
            if (window.Html5Qrcode) {
                return startHtml5Scanner();
            }
            if ('BarcodeDetector' in window) {
                fallbackController = await startFallbackScanner();
                if (fallbackController) {
                    startButton.dataset.state = 'running';
                    startButton.textContent = 'Stop Camera Scan';
                    setStatus('Camera scanner ready (fallback mode).');
                    return true;
                }
            }
            return false;
        }

        async function startHtml5Scanner() {
            try {
                if (!html5Scanner) {
                    html5Scanner = new Html5Qrcode(cameraRegion.id);
                }
                cameraRegion.innerHTML = '';
                await html5Scanner.start(
                    { facingMode: 'environment' },
                    { fps: 10, qrbox: 240 },
                    (decodedText) => {
                        if (!decodedText) {
                            return;
                        }
                        qrInput.value = decodedText.trim();
                        form.requestSubmit();
                        stopScanner();
                    },
                    () => {}
                );
                startButton.dataset.state = 'running';
                startButton.textContent = 'Stop Camera Scan';
                setStatus('Camera scanner ready (high fidelity).');
                return true;
            } catch (error) {
                console.error(error);
                await stopScanner();
                setStatus('Camera scanner could not start. Trying fallback…', 'text-warning fw-semibold');
                return false;
            }
        }

        async function stopScanner() {
            if (html5Scanner) {
                await html5Scanner.stop().catch(() => {});
                html5Scanner.clear();
                html5Scanner = null;
            }
            if (fallbackController) {
                fallbackController.stop();
                fallbackController = null;
            }
            startButton.dataset.state = '';
            startButton.textContent = 'Start Camera Scan';
            cameraRegion.innerHTML = '<div class="text-center text-muted small">Camera idle</div>';
            startButton.classList.remove('disabled');
            setStatus('Camera idle. Ready for manual scans.', 'text-white-50 fw-semibold');
        }

        async function startFallbackScanner() {
            let stream;
            let detector;
            let detectionTimer;
            const video = document.createElement('video');
            video.className = 'w-100 rounded';
            video.setAttribute('playsinline', 'true');
            video.muted = true;
            cameraRegion.innerHTML = '';
            cameraRegion.appendChild(video);

            try {
                detector = new BarcodeDetector({ formats: ['qr_code'] });
                stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } });
                video.srcObject = stream;
                await video.play();

                const scanFrame = async () => {
                    if (!detector) return;
                    try {
                        const codes = await detector.detect(video);
                        if (codes.length > 0) {
                            qrInput.value = codes[0].rawValue.trim();
                            form.requestSubmit();
                            stop();
                            return;
                        }
                    } catch (error) {
                        console.error(error);
                    }
                    detectionTimer = requestAnimationFrame(scanFrame);
                };

                detectionTimer = requestAnimationFrame(scanFrame);
            } catch (error) {
                console.error(error);
                stop();
                setStatus('Fallback scanner unavailable. Please allow camera access.', 'text-warning fw-semibold');
                return null;
            }

            function stop() {
                if (detectionTimer) {
                    cancelAnimationFrame(detectionTimer);
                    detectionTimer = null;
                }
                if (stream) {
                    stream.getTracks().forEach((track) => track.stop());
                    stream = null;
                }
                if (video.srcObject) {
                    video.pause();
                    video.srcObject = null;
                }
                detector = null;
            }

            return { stop };
        }
    }
})();
