<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);

if(!isset($_SESSION['role']) || $_SESSION['role'] != "organizer"){
    die("No access");
}

$user_id = isset($_SESSION['id']) ? (int)$_SESSION['id'] : 0;

include(__DIR__ . "/../../config/db.php");
include(__DIR__ . "/../../templates/header.php");
include(__DIR__ . "/../../templates/sidebar.php");

$events = mysqli_query($conn,"
SELECT 
e.id,
e.title,
e.event_date
FROM events e
JOIN organizers o ON e.organizer_id = o.id
WHERE o.user_id = '$user_id'
AND e.status = 'upcoming'
ORDER BY e.event_date ASC
");
?>


<meta name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="/SEAT/assets/css/organizer/qrScanner.css">
<script src="https://unpkg.com/html5-qrcode"></script>

<div class="scannerPage">

<h2>QR Code Scanner</h2>
<p class="subtitle">Scan participant tickets for attendance tracking</p>

<!-- EVENT -->
<div class="selectCard">
<label>Select Event</label>

<select id="eventSelect" class="eventSelect">
<?php while($e=mysqli_fetch_assoc($events)): ?>
<option value="<?= $e['id'] ?>">
<?= $e['title'] ?> - <?= date("d/m/Y", strtotime($e['event_date'])) ?>
</option>
<?php endwhile; ?>
</select>
</div>

<div class="scannerGrid">

<!-- SCANNER -->
<div class="scannerCard">

<h4>Scan QR Code</h4>

<div style="margin-bottom:10px;">
<label>Camera</label>
<select id="cameraSelect" class="eventSelect">
    <option value="environment" selected>Back Camera</option>
    <option value="user">Front Camera</option>
</select>
</div>


<div class="cameraBox">
    <div id="reader"></div>
</div>

<button
    onclick="startScanner()"
    class="scanBtn"
    id="cameraBtn">
    Open Camera Scanner
</button>

<div class="uploadBox" id="uploadSection">
    <input
        type="file"
        id="fileInput"
        accept="image/*"
        onchange="scanFile(this)">
</div>

<div class="manualBox">
<p>Manual Ticket Entry</p>

<div class="manualRow">
<input type="text" id="manualTicket" placeholder="Enter Ticket ID">
<button onclick="submitManual()">Validate</button>
</div>

</div>

</div>

<!-- RESULT -->
<div class="resultCard">

<h4>Scan Result</h4>

<div id="scanResult">
<div class="emptyResult">No ticket scanned yet</div>
</div>

</div>

</div>
</div>

<script>

let html5Qr = null;
let scannerStarted = false;
let scanLock = false;

const scannedQRs = new Map();
const QR_COOLDOWN = 5000;

const soundSuccess = new Audio("/SEAT/assets/sound/success.mp3");
const soundError = new Audio("/SEAT/assets/sound/error.mp3");

soundSuccess.preload = "auto";
soundError.preload = "auto";

soundSuccess.volume = 1;
soundError.volume = 1;

function unlockAudio(){
    soundSuccess.play().then(()=>{soundSuccess.pause();soundSuccess.currentTime=0;}).catch(()=>{});
    soundError.play().then(()=>{soundError.pause();soundError.currentTime=0;}).catch(()=>{});
}

function initReader(){
    if(!html5Qr){
        html5Qr = new Html5Qrcode("reader");
    }
}

function updateUIState(isScanning){

    let cameraBtn =
    document.getElementById("cameraBtn");

    if(isScanning){
        cameraBtn.innerText = "Stop Camera";
    }else{
        cameraBtn.innerText = "Open Camera Scanner";
    }
}

function startScanner(){

    const cameraType =
    document.getElementById("cameraSelect").value;

    initReader();
    unlockAudio();

    if(scannerStarted){
        stopScanner();
        return;
    }

    html5Qr.start(
        { facingMode: cameraType },
        {
            fps: 15,
            qrbox: {
                width: 250,
                height: 250
            }
        },
        onScanSuccess,
        () => {}
    )
    .then(() => {

        scannerStarted = true;
        updateUIState(true);

    })
    .catch(err => {

        console.log(err);

        alert(
            "Camera permission denied or unavailable"
        );

    });
}

function stopScanner(){

    if(!html5Qr || !scannerStarted){
        return;
    }

    html5Qr.stop()
    .then(() => {

        scannerStarted = false;
        scanLock = false;

        scannedQRs.clear();

        updateUIState(false);

        document.getElementById("scanResult").innerHTML =
        `<div class="emptyResult">
            No ticket scanned yet
        </div>`;

    })
    .catch(err => console.log(err));
}


function onScanSuccess(decodedText){

    const now = Date.now();

    if(scanLock){
        return;
    }

    if(scannedQRs.has(decodedText)){

        const previousScan =
        scannedQRs.get(decodedText);

        if(
            now - previousScan
            < QR_COOLDOWN
        ){
            return;
        }
    }

    scanLock = true;

    scannedQRs.set(
        decodedText,
        now
    );

    processToken(decodedText)
    .finally(() => {

        setTimeout(() => {

            scanLock = false;

        }, 800);

    });
}


function processToken(token){

    let event_id = document.getElementById("eventSelect").value;

    return fetch("validate_ticket.php",{
        method:"POST",
        headers:{ "Content-Type":"application/json" },
        body:JSON.stringify({ token, event_id })
    })
    .then(res => res.json())
    .then(data => {

        let box = document.getElementById("scanResult");
        const scannedTime = new Date().toLocaleString();

        if(data.valid){

            soundSuccess.currentTime = 0;
            soundSuccess.play().catch(()=>{});

            box.innerHTML = `
            <div class="scanSuccess animateResult">

                <div class="status success">
                    <i class="fa fa-check-circle"></i>
                    VALID TICKET
                </div>

                <div class="infoGrid">

                    <div class="userRow">
                        <span>Event Name</span>
                        <b>${data.title}</b>
                    </div>

                    <div class="userRow">
                        <span>Event Date</span>
                        <b>${data.event_date ?? '-'}</b>
                    </div>

                    <div class="userRow">
                        <span>Participant Name</span>
                        <b>${data.name}</b>
                    </div>

                    <div class="userRow">
                        <span>ID</span>
                        <b>${data.matric}</b>
                    </div>
                    
                        <div class="userRow">
                        <span>Ticket</span>
                        <b>${data.ticket ?? token}</b>
                    </div>

                    <div class="userRow">
                        <span>Scanned Date</span>
                        <b>${scannedTime}</b>
                    </div>

                </div>

            </div>`;
        }
        else{

            soundError.currentTime = 0;
            soundError.play().catch(()=>{});

            box.innerHTML = `
            <div class="scanError animateResult">

                <div class="status invalid">
                    <i class="fa fa-times-circle"></i>
                    INVALID TICKET
                </div>

                <div class="infoGrid">

                    <div class="userRow">
                        <span>Event</span>
                        <b>${data.title ?? '-'}</b>
                    </div>

                    <div class="userRow">
                        <span>Ticket</span>
                        <b>${data.ticket ?? token}</b>
                    </div>

                    <div class="userRow">
                        <span>Time</span>
                        <b>${scannedTime}</b>
                    </div>

                </div>

                <div class="errorMsg">
                    ${data.message ?? 'Invalid Ticket'}
                </div>

            </div>`;
        }

        document.getElementById("manualTicket").value = "";

    })
    .catch(err => {
        console.log(err);
        soundError.play().catch(()=>{});
    });
}

function submitManual(){

    let input = document.getElementById("manualTicket").value.trim();

    if(!input){
        alert("Enter ticket ID");
        return;
    }

    processToken(input);
}

function triggerUpload(){
    document.getElementById("fileInput").click();
}

async function scanFile(input){

    const file = input.files[0];

    if(!file){
        return;
    }

    initReader();

    try{

        if(scannerStarted){

            await html5Qr.stop();

            scannerStarted = false;

            updateUIState(false);
        }

        const decodedText =
        await html5Qr.scanFile(
            file,
            true
        );

        processToken(decodedText);

        input.value = "";

    }catch(err){

        console.log(err);

        soundError.currentTime = 0;

        soundError.play()
        .catch(()=>{});

        document.getElementById(
            "scanResult"
        ).innerHTML = `
        <div class="scanError animateResult">

            <div class="status invalid">
                <i class="fa fa-times-circle"></i>
                INVALID IMAGE
            </div>

            <div class="errorMsg">
                Cannot detect QR code
            </div>

        </div>`;
    }
}

</script>