<?php
if (session_status() === PHP_SESSION_NONE) session_start();
if (!isset($_SESSION['user_id'])) { header('Location: ../index.php'); exit; }
require_once '../config.php';
require_once '../includes/canteen_helpers.php';
canteen_require_active();
canteen_require_role(['admin', 'headteacher']);
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hardware Compatibility Test — EduTrack</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
    <link rel="stylesheet" href="../css/style.css">
    <style>
        .test-row { border-bottom: 1px solid #e9ecef; padding: .85rem 0; }
        .test-row:last-child { border-bottom: none; }
        .status-badge {
            min-width: 90px; text-align: center;
            font-weight: 600; font-size: .85rem;
        }
        .camera-thumb {
            width: 100%; max-width: 320px; height: 180px;
            object-fit: cover; border-radius: 8px;
            background: #000; display: block;
        }
        #lightingBar {
            height: 14px; border-radius: 7px;
            background: linear-gradient(90deg, #dc3545 0%, #ffc107 40%, #198754 80%);
            position: relative;
        }
        #lightingIndicator {
            position: absolute; top: -4px;
            width: 10px; height: 22px;
            background: #fff; border: 2px solid #333;
            border-radius: 5px; transform: translateX(-50%);
            transition: left .3s;
        }
    </style>
</head>
<body>
<div class="wrapper">
    <nav id="sidebar" class="sidebar">
        <?php echo buildSidebar('canteen/hardware_test.php'); ?>
    </nav>
    <div class="main-content">
        <header class="header">
            <button class="btn-toggle" id="sidebarToggle"><i class="fas fa-bars"></i></button>
            <div class="header-right">
                <div class="dropdown">
                    <button class="btn btn-link dropdown-toggle" type="button" data-bs-toggle="dropdown">
                        <i class="fas fa-user-circle me-2"></i><?php echo htmlspecialchars((string)($_SESSION['full_name'] ?? '')); ?>
                    </button>
                    <ul class="dropdown-menu dropdown-menu-end">
                        <li><a class="dropdown-item" href="../dashboard.php"><i class="fas fa-home me-2"></i>Dashboard</a></li>
                    </ul>
                </div>
            </div>
        </header>
        <main class="content">
            <div class="content-header">
                <h2><i class="fas fa-microchip me-2"></i>Hardware Compatibility Test</h2>
                <p class="text-muted">Browser-side check — no server calls. Results shown instantly.</p>
            </div>

            <!-- ── API Support ─────────────────────────────────────────────── -->
            <div class="card mb-4">
                <div class="card-header fw-semibold"><i class="fas fa-code me-2"></i>Browser API Support</div>
                <div class="card-body py-2 px-3" id="apiTests">
                    <p class="text-muted small"><i class="fas fa-circle-notch fa-spin me-2"></i>Checking…</p>
                </div>
            </div>

            <!-- ── Fingerprint ─────────────────────────────────────────────── -->
            <div class="card mb-4">
                <div class="card-header fw-semibold"><i class="fas fa-fingerprint me-2"></i>Fingerprint Scanner</div>
                <div class="card-body">
                    <div class="row align-items-center g-3">
                        <div class="col-md-8">
                            <p class="mb-1 text-muted small">Tests for a FIDO2 / WebAuthn cross-platform authenticator (USB fingerprint scanner).</p>
                            <p class="mb-2 text-muted small">Supported devices: Hamster Pro 20, Digital Persona U.are.U 4500, Thales K30.</p>
                            <p class="mb-0 text-warning small"><i class="fas fa-exclamation-triangle me-1"></i>Chrome 90+ or Edge 90+ required — Firefox does not support cross-platform FIDO2.</p>
                        </div>
                        <div class="col-md-4 text-center">
                            <div id="fpStatus" class="mb-2">
                                <span class="badge bg-secondary status-badge">Not tested</span>
                            </div>
                            <button class="btn btn-outline-primary btn-sm" id="btnTestFP">
                                <i class="fas fa-fingerprint me-1"></i>Test Fingerprint
                            </button>
                        </div>
                    </div>
                </div>
            </div>

            <!-- ── Camera ─────────────────────────────────────────────────── -->
            <div class="card mb-4">
                <div class="card-header fw-semibold"><i class="fas fa-camera me-2"></i>Camera (Facial Recognition)</div>
                <div class="card-body">
                    <p class="mb-2 text-muted small">Requires USB webcam minimum 720p. Tested: Logitech C270, C920.</p>
                    <div id="cameraTests">
                        <button class="btn btn-outline-primary btn-sm mb-3" id="btnTestCamera">
                            <i class="fas fa-camera me-1"></i>Test Camera
                        </button>
                    </div>
                    <div id="cameraGrid" class="row g-3" style="display:none!important"></div>
                    <!-- Lighting -->
                    <div id="lightingSection" class="mt-3" style="display:none">
                        <div class="d-flex justify-content-between align-items-center mb-1">
                            <span class="small text-muted">Lighting level</span>
                            <span id="lightingLabel" class="small fw-semibold"></span>
                        </div>
                        <div id="lightingBar"><div id="lightingIndicator"></div></div>
                        <div id="lightingMsg" class="small mt-1"></div>
                    </div>
                </div>
            </div>

            <!-- ── Summary ────────────────────────────────────────────────── -->
            <div id="summaryCard" class="card d-none">
                <div class="card-body text-center py-4" id="summaryBody"></div>
            </div>
        </main>
    </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/js/bootstrap.bundle.min.js"></script>
<script>
'use strict';
(function () {

// ── API checks ─────────────────────────────────────────────────────────────
const apiChecks = [
    { name: 'navigator.credentials (WebAuthn)',      pass: () => 'credentials' in navigator },
    { name: 'PublicKeyCredential',                   pass: () => typeof PublicKeyCredential !== 'undefined' },
    { name: 'getUserMedia (camera)',                 pass: () => !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) },
    { name: 'IndexedDB (offline queue)',             pass: () => typeof indexedDB !== 'undefined' },
    { name: 'Service Worker (offline cache)',        pass: () => 'serviceWorker' in navigator },
];

const apiContainer = document.getElementById('apiTests');
let allApiPass = true;
const rows = apiChecks.map(c => {
    const ok = c.pass();
    if (!ok) allApiPass = false;
    return `<div class="test-row d-flex justify-content-between align-items-center">
        <span class="small">${c.name}</span>
        <span class="badge status-badge ${ok ? 'bg-success' : 'bg-danger'}">${ok ? '✓ Supported' : '✗ Missing'}</span>
    </div>`;
});
apiContainer.innerHTML = rows.join('');

// ── Fingerprint test ───────────────────────────────────────────────────────
let fpResult = null;
document.getElementById('btnTestFP').addEventListener('click', async function () {
    const statusEl = document.getElementById('fpStatus');
    statusEl.innerHTML = '<span class="badge bg-warning status-badge"><i class="fas fa-circle-notch fa-spin me-1"></i>Testing…</span>';
    this.disabled = true;

    if (!window.PublicKeyCredential) {
        fpResult = false;
        statusEl.innerHTML = '<span class="badge bg-danger status-badge">✗ No WebAuthn</span>';
        this.disabled = false;
        updateSummary();
        return;
    }

    // Check if platform authenticator is available
    const hasPlatform = await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable().catch(() => false);

    try {
        const challenge = crypto.getRandomValues(new Uint8Array(32));
        await navigator.credentials.get({
            publicKey: {
                challenge,
                rpId: window.location.hostname,
                allowCredentials: [],
                userVerification: 'required',
                authenticatorSelection: { authenticatorAttachment: 'cross-platform' },
                timeout: 20000,
            }
        });
        fpResult = true;
        statusEl.innerHTML = '<span class="badge bg-success status-badge">✓ Scanner detected</span>';
    } catch (err) {
        if (err.name === 'NotAllowedError') {
            // User cancelled — browser + scanner exists, user just cancelled
            fpResult = true;
            statusEl.innerHTML = '<span class="badge bg-success status-badge">✓ Scanner detected</span>';
        } else if (err.name === 'NotSupportedError' || err.name === 'SecurityError') {
            fpResult = false;
            statusEl.innerHTML = '<span class="badge bg-danger status-badge">✗ Not compatible</span>';
        } else {
            // InvalidStateError etc — no credential enrolled but hardware may exist
            fpResult = null;
            statusEl.innerHTML = '<span class="badge bg-warning status-badge">⚠ No enrolled key</span>';
            document.getElementById('btnTestFP').insertAdjacentHTML('afterend',
                '<p class="text-muted small mt-1">No credential enrolled yet — enroll first in Biometric Enrollment, then re-test.</p>');
        }
    }
    this.disabled = false;
    updateSummary();
});

// ── Camera test ────────────────────────────────────────────────────────────
const cameraGrid = document.getElementById('cameraGrid');
const lightingSection = document.getElementById('lightingSection');

document.getElementById('btnTestCamera').addEventListener('click', async function () {
    this.disabled = true;
    this.innerHTML = '<i class="fas fa-circle-notch fa-spin me-1"></i>Enumerating cameras…';

    try {
        // Request permission first so labels appear
        const tempStream = await navigator.mediaDevices.getUserMedia({ video: true });
        tempStream.getTracks().forEach(t => t.stop());

        const devices = await navigator.mediaDevices.enumerateDevices();
        const cameras = devices.filter(d => d.kind === 'videoinput');

        if (cameras.length === 0) {
            document.getElementById('cameraTests').innerHTML =
                '<span class="badge bg-danger status-badge">✗ No camera found</span>';
            updateSummary();
            this.disabled = false;
            return;
        }

        // Show camera cards
        cameraGrid.style.removeProperty('display');
        cameraGrid.innerHTML = '';
        cameras.forEach((cam, i) => {
            const col = document.createElement('div');
            col.className = 'col-md-6';
            col.innerHTML = `
                <div class="border rounded p-2">
                    <p class="small fw-semibold mb-1"><i class="fas fa-camera me-1"></i>Camera ${i+1}: ${cam.label || 'Unknown camera'}</p>
                    <video id="camThumb_${i}" class="camera-thumb" autoplay playsinline muted></video>
                    <p id="camStatus_${i}" class="small text-muted mt-1 mb-0"><i class="fas fa-circle-notch fa-spin me-1"></i>Starting…</p>
                </div>`;
            cameraGrid.appendChild(col);
        });

        this.innerHTML = '<i class="fas fa-check me-1"></i>' + cameras.length + ' camera(s) found';
        document.getElementById('cameraTests').insertAdjacentHTML('afterend',
            `<p class="small text-success mb-2"><i class="fas fa-check-circle me-1"></i>${cameras.length} camera(s) detected</p>`);

        // Start first camera (environment-facing if possible), show lighting
        let activeStream = null;
        try {
            activeStream = await navigator.mediaDevices.getUserMedia({
                video: { deviceId: { ideal: cameras[0].deviceId }, width: { ideal: 1280 }, height: { ideal: 720 } }
            });
            const vid = document.getElementById('camThumb_0');
            vid.srcObject = activeStream;
            await vid.play();
            document.getElementById('camStatus_0').innerHTML = '<span class="text-success">✓ Live preview</span>';

            // Lighting check
            lightingSection.style.display = 'block';
            checkLighting(vid);
        } catch {
            document.getElementById('camStatus_0').innerHTML = '<span class="text-danger">✗ Could not start</span>';
        }

        // Other cameras — just enumerate, don't start (permission)
        for (let i = 1; i < cameras.length; i++) {
            document.getElementById(`camStatus_${i}`).innerHTML = '<span class="text-muted">Available (not started)</span>';
        }

        updateSummary();
    } catch {
        document.getElementById('cameraTests').innerHTML =
            '<span class="badge bg-danger status-badge">✗ Camera access denied</span>';
        updateSummary();
    }
    this.disabled = false;
});

// ── Lighting check ─────────────────────────────────────────────────────────
function checkLighting(video) {
    const cvs = document.createElement('canvas');
    const ctx = cvs.getContext('2d', { willReadFrequently: true });

    function measure() {
        if (video.readyState < 2) { requestAnimationFrame(measure); return; }
        cvs.width  = Math.floor(video.videoWidth  / 4);
        cvs.height = Math.floor(video.videoHeight / 4);
        ctx.drawImage(video, 0, 0, cvs.width, cvs.height);
        const data  = ctx.getImageData(0, 0, cvs.width, cvs.height).data;
        let sum = 0;
        for (let i = 0; i < data.length; i += 4) {
            sum += 0.299 * data[i] + 0.587 * data[i+1] + 0.114 * data[i+2];
        }
        const avg = sum / (data.length / 4);
        const pct = Math.min(100, (avg / 255) * 100);

        document.getElementById('lightingIndicator').style.left = pct + '%';

        const labelEl = document.getElementById('lightingLabel');
        const msgEl   = document.getElementById('lightingMsg');
        if (avg < 60) {
            labelEl.textContent = 'Too dark (' + Math.round(avg) + '/255)';
            labelEl.className = 'small fw-semibold text-danger';
            msgEl.innerHTML = '<span class="text-danger"><i class="fas fa-exclamation-triangle me-1"></i>Lighting is too low. Add frontal lighting or move to a brighter area.</span>';
        } else if (avg < 120) {
            labelEl.textContent = 'Low (' + Math.round(avg) + '/255)';
            labelEl.className = 'small fw-semibold text-warning';
            msgEl.innerHTML = '<span class="text-warning"><i class="fas fa-exclamation-circle me-1"></i>Lighting is below optimal. Facial recognition may be less accurate.</span>';
        } else {
            labelEl.textContent = 'Good (' + Math.round(avg) + '/255)';
            labelEl.className = 'small fw-semibold text-success';
            msgEl.innerHTML = '<span class="text-success"><i class="fas fa-check-circle me-1"></i>Lighting is good for facial recognition.</span>';
        }

        setTimeout(measure, 1000); // re-check every second
    }
    requestAnimationFrame(measure);
}

// ── Summary ────────────────────────────────────────────────────────────────
function updateSummary() {
    const card = document.getElementById('summaryCard');
    const body = document.getElementById('summaryBody');

    if (!allApiPass) {
        card.classList.remove('d-none');
        body.innerHTML = '<i class="fas fa-times-circle fa-3x text-danger mb-3"></i><h5 class="text-danger">Browser Not Compatible</h5><p class="text-muted">Some required browser APIs are missing. Please use Chrome 90+ or Edge 90+.</p>';
        return;
    }

    if (fpResult === true) {
        card.classList.remove('d-none');
        body.innerHTML = '<i class="fas fa-check-circle fa-3x text-success mb-3"></i><h5 class="text-success">All systems ready — proceed to biometric enrollment.</h5><div class="mt-3"><a href="enroll_fingerprint.php" class="btn btn-primary me-2"><i class="fas fa-fingerprint me-1"></i>Enroll Fingerprints</a><a href="enroll_facial.php" class="btn btn-outline-primary"><i class="fas fa-user-circle me-1"></i>Enroll Facial</a></div>';
    }
}

})();
</script>
</body>
</html>
