<?php
/**
 * Voting Kiosk — voter-facing PIN-entry screen
 *
 * Flow:
 *   1. PIN entry  — voter types the 5-character PIN they received at the check-in desk
 *   2. Confirm    — voter sees their photo + name and confirms identity
 *   3. Vote       — system sets session and redirects to election-vote.php
 *   4. After vote — receipt page auto-resets to step 1 for the next voter
 */

if (!defined('BASE_PATH')) {
    require_once __DIR__ . '/../../config/app.php';
    require_once __DIR__ . '/../../includes/session-bootstrap.php';
    nazareth_bootstrap_session_cookie();
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }
    require_once __DIR__ . '/../../config/database.php';
}

require_once __DIR__ . '/../../includes/auth.php';
require_once __DIR__ . '/../../includes/voting.php';
require_once __DIR__ . '/../../includes/fellowships.php';

if (empty($id)) {
    http_response_code(404);
    exit('Election not found.');
}

if (!isVotingEnabled()) {
    exit('The voting system is currently disabled. Please check with the election administrator.');
}

$election = getElection($id);
if (!$election || $election['status'] !== 'active') {
    exit('This election is not currently active.');
}

// ── Step 2: voter confirmed identity → set session and redirect to vote ───────
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'confirm_identity') {
    $memberId = (int)($_POST['member_id'] ?? 0);
    $pin      = strtoupper(trim($_POST['pin'] ?? ''));

    if ($memberId > 0 && $pin) {
        // Re-validate PIN + eligibility before granting access
        $voter = getVoterByPin($id, $pin);
        if (!$voter || (int)$voter['member_id'] !== $memberId) {
            header('Location: ' . BASE_PATH . '/voting/kiosk/' . $id . '?error=' . urlencode('Invalid PIN. Please try again or see the check-in desk.'));
            exit;
        }
        if ($voter['pin_used']) {
            header('Location: ' . BASE_PATH . '/voting/kiosk/' . $id . '?error=' . urlencode('This PIN has already been used. If you have not voted yet, please see the check-in desk.'));
            exit;
        }
        if (!isVoterEligible($id, $memberId)) {
            header('Location: ' . BASE_PATH . '/voting/kiosk/' . $id . '?error=' . urlencode('This member is not on the eligible voter list.'));
            exit;
        }
        if (hasMemberVoted($id, $memberId)) {
            header('Location: ' . BASE_PATH . '/voting/kiosk/' . $id . '?error=' . urlencode('This member has already voted. Thank you!'));
            exit;
        }
        $_SESSION['kiosk_voter_id']    = $memberId;
        $_SESSION['kiosk_election_id'] = (int)$id;
        header('Location: ' . BASE_PATH . '/voting/vote/' . $id . '?kiosk=1');
        exit;
    }
}

// ── Step 1: voter enters PIN → look it up ─────────────────────────────────────
$pinError      = null;
$pendingVoter  = null;
$enteredPin    = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'lookup_pin') {
    $enteredPin = strtoupper(trim($_POST['pin'] ?? ''));
    $enteredPin = preg_replace('/[^A-Z0-9]/', '', $enteredPin);

    if (strlen($enteredPin) !== 5) {
        $pinError = 'Please enter your full 5-character PIN.';
    } else {
        $voter = getVoterByPin($id, $enteredPin);
        if (!$voter) {
            $pinError = 'PIN not recognised. Please check your slip or see the check-in desk.';
        } elseif ($voter['pin_used']) {
            $pinError = 'This PIN has already been used. If you have not voted, please see the check-in desk.';
        } elseif (hasMemberVoted($id, (int)$voter['member_id'])) {
            $pinError = 'You have already voted in this election. Thank you!';
        } else {
            // Valid PIN — pre-load the confirm screen
            $pendingVoter = $voter;
        }
    }
}


$pageTitle = 'Voting Kiosk — ' . htmlspecialchars($election['title']);
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><?= htmlspecialchars($pageTitle) ?></title>
    <link rel="icon" href="<?= BASE_PATH ?>/public/img/logo.png" type="image/png">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="<?= BASE_PATH ?>/public/css/style.css?v=<?= filemtime(__DIR__ . '/../../public/css/style.css') ?>">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" crossorigin="anonymous" referrerpolicy="no-referrer">
    <style>
        *, *::before, *::after { box-sizing: border-box; }
        html, body { height: 100%; margin: 0; }
        body { background: #0b1b89; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100vh; font-family: 'Inter', sans-serif; }

        .kiosk-wrap { width: 100%; max-width: 520px; padding: 2rem 1.25rem; }

        /* Header */
        .kiosk-header { display: flex; flex-direction: column; align-items: center; gap: 0.6rem; margin-bottom: 2rem; text-align: center; }
        .kiosk-logo   { height: 56px; width: auto; filter: drop-shadow(0 2px 6px rgba(0,0,0,0.3)); }
        .kiosk-title h1 { font-size: 1.375rem; font-weight: 700; margin: 0 0 0.2rem; color: #fff; }
        .kiosk-title p  { font-size: 0.875rem; color: rgba(255,255,255,0.65); margin: 0; }

        /* PIN entry card */
        .pin-card {
            background: #fff; border-radius: 16px;
            padding: 2.5rem 2rem;
            box-shadow: 0 2px 12px rgba(0,0,0,0.07);
            text-align: center;
        }
        .pin-card-icon {
            font-size: 2.5rem; margin-bottom: 1rem; display: block;
        }
        .pin-card h2 { font-size: 1.25rem; margin: 0 0 0.4rem; }
        .pin-card .pin-card-sub { font-size: 0.9rem; color: #718096; margin-bottom: 2rem; }

        /* 5-box PIN input */
        .pin-inputs {
            display: flex; gap: 0.6rem; justify-content: center; margin-bottom: 1.5rem;
        }
        .pin-inputs input {
            width: 54px; height: 64px;
            border: 2px solid #e2e8f0; border-radius: 10px;
            text-align: center; font-size: 1.75rem; font-weight: 700;
            text-transform: uppercase; background: #f8fafc;
            transition: border-color 0.15s;
            -webkit-appearance: none;
            caret-color: transparent;
        }
        .pin-inputs input:focus {
            outline: none; border-color: #1e3a5f; background: #fff;
        }
        .pin-inputs input.filled { border-color: #1e3a5f; background: #eff6ff; }
        .pin-inputs input.error  { border-color: #dc2626; background: #fef2f2; }

        .pin-submit-btn {
            width: 100%; padding: 0.85rem; font-size: 1rem; font-weight: 600;
            border-radius: 10px; border: none; cursor: pointer;
            background: #1e3a5f; color: #fff;
            transition: background 0.15s;
        }
        .pin-submit-btn:hover { background: #162d4a; }
        .pin-submit-btn:disabled { background: #94a3b8; cursor: default; }

        /* Error bar */
        .kiosk-error-bar {
            background: rgba(255,255,255,0.12); border: 1px solid rgba(255,100,100,0.5);
            border-radius: 10px; padding: 0.85rem 1rem;
            margin-bottom: 1.25rem; color: #fca5a5;
            font-size: 0.9rem; text-align: center;
        }

        /* Voting inactive notice */
        .kiosk-inactive {
            background: rgba(255,255,255,0.1); border: 1px solid rgba(255,200,80,0.45);
            border-radius: 10px; padding: 0.85rem 1rem;
            margin-bottom: 1.25rem; color: #fde68a;
            font-size: 0.9rem; text-align: center;
        }

        /* Fullscreen splash */
        #fs-splash {
            position: fixed; inset: 0; z-index: 9999;
            background: #0b1b89;
            display: flex; flex-direction: column;
            align-items: center; justify-content: center;
            gap: 1.5rem; cursor: pointer;
            user-select: none;
        }
        #fs-splash img { height: 80px; filter: drop-shadow(0 4px 12px rgba(0,0,0,0.4)); }
        #fs-splash h1  { color: #fff; font-size: 2rem; font-weight: 800; margin: 0; text-align: center; line-height: 1.25; }
        #fs-splash p   { color: rgba(255,255,255,0.65); font-size: 1rem; margin: 0; text-align: center; }
        .fs-tap-badge  {
            margin-top: 1rem;
            background: rgba(255,255,255,0.12);
            border: 2px solid rgba(255,255,255,0.3);
            border-radius: 999px; padding: 0.65rem 2rem;
            color: #fff; font-size: 1rem; font-weight: 600;
            display: flex; align-items: center; gap: 0.6rem;
            animation: pulse 2s ease-in-out infinite;
        }
        @keyframes pulse {
            0%, 100% { box-shadow: 0 0 0 0 rgba(255,255,255,0.25); }
            50%       { box-shadow: 0 0 0 12px rgba(255,255,255,0); }
        }

        /* Stats strip */
        .kiosk-stats { display: flex; gap: 0.6rem; margin-bottom: 1.5rem; flex-wrap: wrap; }
        .kiosk-stat  { flex: 1; min-width: 80px; background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.15); border-radius: 8px; padding: 0.6rem; text-align: center; }
        .kiosk-stat .ks-num { font-size: 1.5rem; font-weight: 700; line-height: 1; color: #fff; }
        .kiosk-stat .ks-lbl { font-size: 0.7rem; color: rgba(255,255,255,0.6); margin-top: 0.15rem; }

        /* Identity confirmation overlay */
        .confirm-overlay {
            position: fixed; inset: 0; background: rgba(0,0,0,0.55);
            display: flex; align-items: center; justify-content: center;
            z-index: 1000; padding: 1.25rem;
        }
        .confirm-box {
            background: #fff; border-radius: 18px; padding: 2.25rem 2rem;
            max-width: 360px; width: 100%; text-align: center;
            box-shadow: 0 10px 40px rgba(0,0,0,0.2);
        }
        .confirm-box img {
            width: 110px; height: 110px; border-radius: 50%;
            object-fit: cover; margin-bottom: 1rem;
            border: 3px solid #1e3a5f;
        }
        .confirm-name { font-size: 1.25rem; font-weight: 700; margin-bottom: 0.2rem; }
        .confirm-meta { font-size: 0.875rem; color: #718096; margin-bottom: 0.25rem; }
        .confirm-question { font-size: 0.9375rem; margin: 1rem 0 1.5rem; color: #374151; }
        .confirm-actions { display: flex; gap: 0.75rem; justify-content: center; }
    </style>
</head>
<body>

<!-- Fullscreen splash — shown on load and whenever fullscreen is exited -->
<div id="fs-splash" onclick="enterFullscreen()">
    <img src="<?= BASE_PATH ?>/public/img/logo.png" alt="" onerror="this.style.display='none'">
    <div style="text-align:center;">
        <h1><?= htmlspecialchars($election['title']) ?></h1>
        <p><?= $election['type'] === 'presbyters' ? "Presbyters' Elections" : "Fellowship Elections" ?></p>
    </div>
    <div class="fs-tap-badge">
        <i class="fas fa-hand-pointer"></i> Tap anywhere to begin voting
    </div>
</div>

<div class="kiosk-wrap">
    <div class="kiosk-header">
        <img src="<?= BASE_PATH ?>/public/img/logo.png" alt="" class="kiosk-logo" onerror="this.style.display='none'">
        <div class="kiosk-title">
            <h1><?= htmlspecialchars($election['title']) ?></h1>
            <p>Enter your voting PIN to cast your vote</p>
        </div>
    </div>

    <?php if ($election['status'] !== 'active'): ?>
    <div class="kiosk-inactive">
        <strong>Voting is not active.</strong> This election is currently <em><?= htmlspecialchars($election['status']) ?></em>.
        Only the voting manager can activate it.
    </div>
    <?php endif; ?>

    <?php
    $urlError = $_GET['error'] ?? '';
    $showUrlError = !empty($urlError) && stripos($urlError, 'Please use the voting kiosk') === false;
    ?>
    <?php if ($showUrlError): ?>
    <div class="kiosk-error-bar"><?= htmlspecialchars($urlError) ?></div>
    <?php endif; ?>

    <?php if ($pinError): ?>
    <div class="kiosk-error-bar"><?= htmlspecialchars($pinError) ?></div>
    <?php endif; ?>


    <div class="pin-card">
        <span class="pin-card-icon">&#128274;</span>
        <h2>Enter Your Voting PIN</h2>
        <p class="pin-card-sub">Type the 5-character PIN you received at the check-in desk</p>

        <form method="post" id="pin-form" autocomplete="off">
            <input type="hidden" name="action" value="lookup_pin">
            <div class="pin-inputs" id="pin-inputs">
                <?php for ($i = 0; $i < 5; $i++): ?>
                <input type="text" maxlength="1"
                       name="pin_digit_<?= $i ?>"
                       id="pd<?= $i ?>"
                       inputmode="text"
                       autocomplete="off"
                       class="<?= ($pinError ? 'error' : '') ?>"
                       value="">
                <?php endfor; ?>
                <input type="hidden" name="pin" id="pin-combined" value="">
            </div>
            <button type="submit" class="pin-submit-btn" id="pin-submit" disabled>
                <i class="fas fa-arrow-right" style="margin-right:0.4rem;"></i> Continue
            </button>
        </form>
    </div>
</div>

<?php if ($pendingVoter):
    $pName   = trim(($pendingVoter['first_name'] ?? '') . ' ' . ($pendingVoter['middle_name'] ?? '') . ' ' . ($pendingVoter['last_name'] ?? ''));
    $pFellow = getMemberFellowship($pendingVoter['date_of_birth'] ?? null, $pendingVoter['gender'] ?? '');
    $pPhoto  = !empty($pendingVoter['photo'])
        ? BASE_PATH . '/public/uploads/members/' . htmlspecialchars($pendingVoter['photo'])
        : BASE_PATH . '/public/img/' . (strtolower($pendingVoter['gender'] ?? '') === 'female' ? 'female' : 'male') . '.jpg';
?>
<div class="confirm-overlay" id="confirm-overlay">
    <div class="confirm-box">
        <img src="<?= $pPhoto ?>" alt=""
             onerror="this.src='<?= BASE_PATH ?>/public/img/<?= strtolower($pendingVoter['gender'] ?? '') === 'female' ? 'female' : 'male' ?>.jpg'">
        <div class="confirm-name"><?= htmlspecialchars($pName) ?></div>
        <div class="confirm-meta"><?= htmlspecialchars($pFellow ?? '') ?></div>
        <p class="confirm-question">Is this you?</p>
        <div class="confirm-actions">
            <button type="button" class="btn btn-outline" onclick="resetKiosk()">
                <i class="fas fa-times"></i> Not me
            </button>
            <form method="post" style="display:inline;" id="confirm-form">
                <input type="hidden" name="action"    value="confirm_identity">
                <input type="hidden" name="member_id" value="<?= (int)$pendingVoter['member_id'] ?>">
                <input type="hidden" name="pin"       value="<?= htmlspecialchars($enteredPin) ?>">
                <button type="submit" class="btn" style="background:#059669;border-color:#059669;color:#fff;">
                    <i class="fas fa-check"></i> Yes, that's me
                </button>
            </form>
        </div>
    </div>
</div>
<?php endif; ?>

<script>
// ── Fullscreen management ────────────────────────────────────────────────────
var splash = document.getElementById('fs-splash');

function enterFullscreen() {
    var el = document.documentElement;
    var req = el.requestFullscreen || el.webkitRequestFullscreen || el.mozRequestFullScreen || el.msRequestFullscreen;
    if (req) {
        req.call(el).catch(function () {});
    }
    if (splash) splash.style.display = 'none';
    // Focus first PIN box
    var first = document.getElementById('pd0');
    if (first) setTimeout(function () { first.focus(); }, 100);
}

// Re-show splash whenever fullscreen is exited (Escape key, etc.)
document.addEventListener('fullscreenchange',       onFsChange);
document.addEventListener('webkitfullscreenchange', onFsChange);
document.addEventListener('mozfullscreenchange',    onFsChange);
document.addEventListener('MSFullscreenChange',     onFsChange);

function onFsChange() {
    var inFs = !!(document.fullscreenElement || document.webkitFullscreenElement ||
                  document.mozFullScreenElement || document.msFullscreenElement);
    if (!inFs && splash) {
        // Reset the PIN form so the next voter starts clean
        resetKiosk();
        splash.style.display = 'flex';
    }
}

// ── Keyboard / navigation lock ───────────────────────────────────────────────
(function () {
    document.addEventListener('contextmenu', function (e) { e.preventDefault(); });
    document.addEventListener('keydown', function (e) {
        var ctrl = e.ctrlKey || e.metaKey;
        if (
            e.key === 'F5' ||
            (ctrl && ['r','R','w','W','t','T','l','L','n','N'].includes(e.key)) ||
            (e.altKey && (e.key === 'ArrowLeft' || e.key === 'ArrowRight')) ||
            e.key === 'F12'
        ) {
            e.preventDefault();
        }
    });
    window.addEventListener('beforeunload', function (e) {
        if (!document.querySelector('form[data-submitting]')) {
            e.preventDefault();
            e.returnValue = '';
        }
    });
    document.querySelectorAll('form').forEach(function (f) {
        f.addEventListener('submit', function () { f.setAttribute('data-submitting', '1'); });
    });
})();

(function () {
    var inputs   = document.querySelectorAll('#pin-inputs input[id^="pd"]');
    var combined = document.getElementById('pin-combined');
    var submit   = document.getElementById('pin-submit');

    function syncCombined() {
        var val = '';
        inputs.forEach(function (inp) { val += inp.value.toUpperCase(); });
        if (combined) combined.value = val;
        if (submit)   submit.disabled = val.length < 5;
        inputs.forEach(function (inp) {
            inp.value = inp.value.toUpperCase();
            inp.classList.toggle('filled', inp.value.length > 0);
        });
    }

    inputs.forEach(function (inp, idx) {
        // On key down: handle backspace to move focus back
        inp.addEventListener('keydown', function (e) {
            if (e.key === 'Backspace' && !inp.value && idx > 0) {
                inputs[idx - 1].focus();
                inputs[idx - 1].value = '';
                syncCombined();
                e.preventDefault();
            }
        });

        // On input: move to next box
        inp.addEventListener('input', function () {
            var v = inp.value.replace(/[^A-Za-z0-9]/g, '').toUpperCase();
            inp.value = v ? v[v.length - 1] : '';
            syncCombined();
            if (inp.value && idx < inputs.length - 1) {
                inputs[idx + 1].focus();
            }
        });

        // On paste: distribute characters across boxes
        inp.addEventListener('paste', function (e) {
            e.preventDefault();
            var pasted = (e.clipboardData || window.clipboardData).getData('text')
                          .replace(/[^A-Za-z0-9]/g, '').toUpperCase().slice(0, 5);
            pasted.split('').forEach(function (ch, i) {
                if (inputs[idx + i]) inputs[idx + i].value = ch;
            });
            syncCombined();
            var next = Math.min(idx + pasted.length, inputs.length - 1);
            inputs[next].focus();
        });
    });

    // Auto-focus first empty box on load
    var firstEmpty = null;
    inputs.forEach(function (inp) { if (!firstEmpty && !inp.value) firstEmpty = inp; });
    if (firstEmpty) firstEmpty.focus();
})();

function resetKiosk() {
    // Hide confirm overlay and clear the PIN boxes so the voter can try again
    var overlay = document.getElementById('confirm-overlay');
    if (overlay) overlay.style.display = 'none';
    document.querySelectorAll('#pin-inputs input[id^="pd"]').forEach(function (inp) {
        inp.value = '';
        inp.classList.remove('filled', 'error');
    });
    var combined = document.getElementById('pin-combined');
    if (combined) combined.value = '';
    var submit = document.getElementById('pin-submit');
    if (submit)  submit.disabled = true;
    var first = document.getElementById('pd0');
    if (first) first.focus();
}
</script>
</body>
</html>
