<?php 

if (!isset($segments) || !defined('APP_ROUTER')) {
    http_response_code(403);
    include $baseDir . "/error-pages/403.php";
    exit;
}

$type = $segments[1] ?? null;
$requested_geraet = htmlspecialchars($segments[2] ?? '');

$allowed_types = ["audioplayer"];

if (!in_array($type, $allowed_types)) {
    http_response_code(400);
    include $baseDir . "/error-pages/400.html";
    exit;
}

$baseDir = $_SERVER['DOCUMENT_ROOT'];

require_once $baseDir . '/../scripts/session_functions.php';

ini_wkvs_session(true);

$csrf_token = $_SESSION['csrf_token'] ?? '';

require $baseDir . '/../scripts/websocket/ws-create-token.php';

$WSaccesstype = "audio";
$WSaccessPermission = "R";

require_once $baseDir . '/../scripts/db/db-verbindung-script-guest.php';
require_once $baseDir . '/../scripts/db/db-functions.php';
require_once $baseDir . '/../scripts/db/db-tables.php';

$stmt = $guest->prepare("SELECT `name`, `id` FROM $db_tabelle_disziplinen WHERE `audiofile` = '1' ORDER BY start_index ASC");

if (!$stmt->execute()) {
  http_response_code(500);
  exit;
}

$result = $stmt->get_result();
$disciplines = $result->fetch_all(MYSQLI_ASSOC);

$lowerDisciplines = array_change_key_case(
    array_column($disciplines, 'id', 'name'),
    CASE_LOWER
);

$disciplines_indexed = array_column($disciplines, 'name', 'id');


if (!array_key_exists($requested_geraet, $lowerDisciplines)) {
    http_response_code(400);
    $message = 'Das gesuchte Gerät kann nicht gefunden werden';
    include $baseDir . "/error-pages/400.php";
    exit;
}

if (!isset($lowerDisciplines[$requested_geraet])) {
    http_response_code(500);
    include $baseDir . "/error-pages/500.html";
    exit;
}

$geraetId = $lowerDisciplines[$requested_geraet];

$WSaccess = (string) $geraetId;

$jsonUrl = '/externe-geraete/json/audio-id-' . $geraetId . '.json';

?>

<!DOCTYPE html>
<html>
<head>
  <title>Remote Audioplayer</title>
  <meta name="robots" content="noindex">
  <script src="/intern/js/jquery/jquery-3.7.1.min.js"></script>
  <script src="/intern/js/custom-msg-display.js"></script>
  <link rel="stylesheet" href="/intern/css/custom-msg-display.css">
  <link rel="stylesheet" href="/externe-geraete/css/audio.css">

</head>
<body>
    <section>
        <div class="header">
            <h1 id="title">Audioplayer</h1>
            <p id="subtitle"><?= $disciplines_indexed[$geraetId] ?></p>
        </div>
        
        <button class="startButton">
            Audioplayer starten
        </button>

        <div class="currentyPlaying hidden">
            Aktuell laufendes Audio: 
            <div class="subDivCurrentyPlaying">
                <span>Dateiname: <span class="spanFilename"></span></span>
                <span class="spanPersonname">Name der Person: 
                    <span class="spanPersonnameName"></span>,
                    <span class="spanPersonnameVorname"></span>
                </span>
            </div>

            <div class="progressDiv">
                <div id="progressContainer">
                    <div id="progressBar"></div>
                </div>

                <span class="progressText"><span id="currentText">0:00</span> / <span id="durationText">0:00</span></span>
            </div>
        </div>

        <div class="content">
            Dies ist der Live Audioplayer. Audio kann über die Kampfrichteransicht gestartet werden.
        </div>
    </section>

    <audio id="peep" preload="auto"></audio>
    <audio id="musicPlayer" preload="auto"></audio>
    <script>
		const WSaccesstype = "<?= $WSaccesstype ?>";
        const WSaccess = "<?= $WSaccess ?>";
        const csrf_token = "<?= $csrf_token ?>";
        const WSaccessPermission = "<?= $WSaccessPermission ?>"

        const jsonUrl = "<?php echo $jsonUrl; ?>";
		
		let ws;

		let firstConnect = true;
        const RETRY_DELAY = 2000;

        const urlAjaxNewWSToken = '/intern/scripts/ajax-create-ws-token.php';

        async function fetchNewWSToken(accesstype, access, accessPermission) {
            try {
                const response = await fetch(urlAjaxNewWSToken, {
                    method: "POST",
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded',
                    },
                    body: new URLSearchParams({ 
                        csrf_token,
                        accesstype, 
                        access, 
                        accessPermission 
                    })
                });

                if (!response.ok) return null;

                const data = await response.json();
                return data.success ? data.token : null;
            } catch (error) {
                console.error("Token fetch failed:", error);
                return null;
            }
        }

        async function startWebSocket() {
            console.log("Attempting WebSocket connection...");

            let token;
            if (firstConnect) {
                token = '<?= generateWSReadToken($WSaccesstype, $WSaccess) ?>';
            } else {
                token = await fetchNewWSToken(WSaccesstype, WSaccess, WSaccessPermission);
            }

            if (!token) {
                console.error("No valid token available. Retrying...");
                scheduleRetry();
                return;
            }

            try {
                ws = new WebSocket(`wss://${window.location.hostname}/ws/?access=token&token=${token}`);
            } catch (err) {
                console.error("Malformed WebSocket URL", err);
                scheduleRetry();
                return;
            }

            ws.onopen = () => {
                console.log("WebSocket connected!");
                if (!firstConnect) {
                    displayMsg(1, "Live Syncronisation wieder verfügbar");
                }
                firstConnect = true;
            };

            ws.onerror = (event) => {
                console.error("WebSocket error observed.");
            };

            ws.onclose = (event) => {
                displayMsg(0, "Live Syncronisation verloren");
                firstConnect = false;

                scheduleRetry();
            };
        }

        function scheduleRetry() {
            console.log(`Retrying in ${RETRY_DELAY}ms...`);
            setTimeout(startWebSocket, RETRY_DELAY);
        }

        startWebSocket();

        const spanFilename = $('.spanFilename');
        const spanPersonname = $('.spanPersonname');
        const spanPersonnameName = $('.spanPersonnameName');
        const spanPersonnameVorname = $('.spanPersonnameVorname');

        const currentyPlaying = $('.currentyPlaying');

        const $progressBar = $('#progressBar');
        const $progressContainer = $('#progressContainer');

        const peep = document.getElementById('peep');
        const music = document.getElementById('musicPlayer');
        const $audio = $('#musicPlayer');

        let lastMusicUrl = null;
        let pollingStarted = false; // ensure we start polling only once

        async function fetchAndHandleMusic() {
            try {
                const response = await fetch(jsonUrl + '?t=' + Date.now(), { cache: 'no-store' });
                const data = await response.json();

                if (!data.audio_path || data.audio_path === 'nan' || data.start == false) {
                    if (!music.paused) {
                        music.pause();
                        music.currentTime = 0;
                    }
                    if (!peep.paused) {
                        peep.pause();
                        peep.currentTime = 0;
                    }
                    lastMusicUrl = null;
                    return;
                }

                peep.src = '/files/music/piep.mp3';
                music.src = data.audio_path;
                music.currentTime = 0;
                peep.play().then(() => {
                    setTimeout(() => {
                        music.play().catch(err => console.log('Music play error:', err));
                    }, 2000);
                }).catch(err => console.log('Peep play error:', err));

                spanFilename.text(data.audio_name ?? '');
                spanPersonnameName.text(data.person.name ?? '');
                spanPersonnameVorname.text(data.person.vorname ?? '');

            } catch (err) {
                console.error('Error fetching JSON:', err);
            }
        }

        function formatTime(seconds) {
            if (isNaN(seconds)) return "0:00";
            const mins = Math.floor(seconds / 60);
            const secs = Math.floor(seconds % 60);
            return mins + ":" + (secs < 10 ? '0' : '') + secs;
        }

        const audioDOM = $audio[0];

        $audio.on('timeupdate', function() {
            if (audioDOM.duration) {
                const percentage = (audioDOM.currentTime / audioDOM.duration) * 100;
                $progressBar.css('width', percentage + '%');
                $('#currentText').text(formatTime(audioDOM.currentTime));
            }
        });

        $audio.on('loadedmetadata', function() {
            $('#durationText').text(formatTime(audioDOM.duration));
        });

        let isActive = false;

        $('.startButton').on('click', function() {
            isActive = !isActive;
            if (isActive) {
                $(this).text('Audioplayer stoppen');
            } else {
                $(this).text('Audioplayer starten');
                currentyPlaying.addClass('hidden');
                if (!music.paused) {
                    music.pause();
                    music.currentTime = 0;
                }
                if (!peep.paused) {
                    peep.pause();
                    peep.currentTime = 0;
                }
            }
            $('section').toggleClass('playerActive', isActive);
            

            if (!pollingStarted) {
                pollingStarted = true;
                ws.addEventListener("message", () => {
                    if (isActive) {
                        fetchAndHandleMusic();
                        currentyPlaying.removeClass('hidden');
                    }
                });    
            }
        });
    </script>
</body>
</html>
