<h3 id='spielerliste' class="section-header-flex">
    <span>Spielerliste</span>
    <div class="filter-container">
        <button id="player-filter-toggle-btn-%%current_world_key%%" class="filter-dropdown-btn">Filter ▾</button>
        <div id="player-filter-dropdown-%%current_world_key%%" class="filter-dropdown">
            <label class="filter-option">
                <input type="checkbox" data-filter="active">
                <span class="status-dot online"></span>
                zuletzt aktiv
            </label>
            <hr class="privilege-separator">
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="interact"> <span class="icon">🖐️</span> Interagieren</label>
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="shout"> <span class="icon">📢</span> Rufen</label>
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="fast"> <span class="icon">🏃</span> Schnell</label>
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="fly"> <span class="icon">🕊️</span> Fliegen</label>
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="give"> <span class="icon">🎁</span> Geben</label>
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="teleport"> <span class="icon">✨</span> Teleportieren</label>
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="areas"> <span class="icon">🗺️</span> Bereiche</label>
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="noclip"> <span class="icon">👻</span> Noclip</label>
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="settime"> <span class="icon">🕒</span> Zeit</label>
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="weather"> <span class="icon">🌦️</span> Wetter</label>
            <label class="filter-option"><input type="checkbox" data-filter="privilege" data-priv="server"> <span class="icon">🛠️</span> Server</label>
        </div>
    </div>
</h3>
<div id='player-info-%%current_world_key%%' class='player-list-container'>
    <p><em>Spielerdaten werden geladen...</em></p>
</div>

<script>
if (!window.playerListLogic_%%current_world_key%%) {
    window.playerListLogic_%%current_world_key%% = {
        masterPlayerData: {},
        playerFilters: { activeOnly: false, privileges: new Set() },

        updatePlayerMarkers: function(playerData) {
            const source = window.playerMarkerSource_%%current_world_key%%;
            if (!source || typeof ol === 'undefined') return;

            source.clear(); // Entferne alle alten Marker

            const features = [];
            const now_epoch = Math.floor(Date.now() / 1000);
            const twentyFourHoursInSeconds = 24 * 60 * 60;
            
            for (const id in playerData) {
                const p = playerData[id];
                const coords = convertMinetestToOpenLayers_%%current_world_key%%(p.posX, p.posZ);
                if (!coords) continue;
                
                const isAdmin = (p.privilege || '').includes('server');
                let lastLoginFormatted = 'unbekannt';
                let statusDotClass = 'offline';
                if (p.last_login) {
                    if ((now_epoch - p.last_login < twentyFourHoursInSeconds)) { statusDotClass = 'online'; }
                    lastLoginFormatted = formatTimestampForDisplay(p.last_login);
                }

                // HINZUGEFÜGT: Erstelle den kombinierten Stil aus Kreis und Text
                const circleStyle = new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: isAdmin ? 7 : 6,
                        fill: new ol.style.Fill({ color: isAdmin ? 'rgba(255, 190, 0, 0.9)' : 'rgba(255, 40, 40, 0.9)' }),
                        stroke: new ol.style.Stroke({ color: '#ffffff', width: isAdmin ? 2 : 1 })
                    })
                });

                const textStyle = new ol.style.Style({
                    text: new ol.style.Text({
                        text: p.name,
                        font: 'bold 11px "Helvetica Neue", Arial, sans-serif',
                        fill: new ol.style.Fill({ color: '#ffffff' }),
                        stroke: new ol.style.Stroke({ color: 'rgba(0, 0, 0, 0.9)', width: 3 }),
                        offsetY: -20, // Positioniert den Text über dem Kreismittelpunkt
                        textAlign: 'center'
                    })
                });

                const feature = new ol.Feature({
                    geometry: new ol.geom.Point(coords),
                    playerData: p,
                    statusDotClass: statusDotClass,
                    lastLoginFormatted: lastLoginFormatted
                });

                // Setze den kombinierten Stil (Kreis und Text) für das Feature
                feature.set('style', [circleStyle, textStyle]);
                features.push(feature);
            }
            source.addFeatures(features);
        },

        renderPlayerListHTML: function(playerData) {
            if (!playerData || Object.keys(playerData).length === 0) {
                return "<p><em>Keine Spieler entsprechen den aktuellen Filtereinstellungen.</em></p>";
            }
            let html = "<div class='player-list-grid'>";
            const now_epoch = Math.floor(Date.now() / 1000);
            const twentyFourHoursInSeconds = 24 * 60 * 60;
            for (const id in playerData) {
                const p = playerData[id];
                const privs = p.privilege ? p.privilege.toLowerCase().split(',') : [];
                const hasServerPriv = privs.includes("server");
                let statusDotClass = "offline";
                let lastLoginFormatted = 'unbekannt';
                if (p.last_login) {
                    if ((now_epoch - p.last_login < twentyFourHoursInSeconds)) { statusDotClass = "online"; }
                    lastLoginFormatted = formatTimestampForDisplay(p.last_login);
                }
                html += `<div class="player-box ${hasServerPriv ? "has-server-priv" : ""}">
                    <div class="player-header">
                        <div class="player-identity"><img src="/images/players/${encodeURIComponent(p.name)}.png?v=%%CACHE_BUSTER%%" class="player-icon" onerror="this.onerror=null;this.src='/%%DEFAULT_PLAYER_SKIN_URL%%?v=%%CACHE_BUSTER%%';"><span class="player-name-status"><span class="status-dot ${statusDotClass}" data-title="Letzter Login: ${lastLoginFormatted}"></span><strong class="player-name">${p.name}</strong></span></div>
                        <div class="player-vitals"><span class="icon" data-title="HP: ${p.hp ?? '?'}">❤️</span><span class="icon" data-title="Atem: ${p.breath ?? '?'}">💨</span><span class="icon" data-title="Ausdauer: ${p.stamina ?? '?'}">🍖</span></div>
                    </div>
                    <hr class="privilege-separator">
                    <div class="player-attributes">
                        <span class="icon privilege ${privs.includes('interact')?'active':''}" data-title="Interagieren">🖐️</span> <span class="icon privilege ${privs.includes('shout')?'active':''}" data-title="Rufen">📢</span>
                        <span class="icon privilege ${privs.includes('fast')?'active':''}" data-title="Schnelles Laufen">🏃</span> <span class="icon privilege ${privs.includes('fly')?'active':''}" data-title="Fliegen">🕊️</span>
                        <span class="icon privilege ${privs.includes('give')?'active':''}" data-title="Geben">🎁</span> <span class="icon privilege ${privs.includes('teleport')?'active':''}" data-title="Teleportieren">✨</span>
                        <span class="icon privilege ${privs.includes('areas')?'active':''}" data-title="Bereiche">🗺️</span> <span class="icon privilege ${privs.includes('noclip')?'active':''}" data-title="Noclip">👻</span>
                        <span class="icon privilege ${privs.includes('settime')?'active':''}" data-title="Zeit setzen">🕒</span> <span class="icon privilege ${privs.includes('weather')?'active':''}" data-title="Wetter">🌦️</span>
                        <span class="icon privilege ${hasServerPriv?'active':''}" data-title="Server-Admin">🛠️</span>
                    </div></div>`;
            }
            html += "</div>";
            return html;
        },

        applyPlayerFiltersAndRender: function() {
            const filteredData = {};
            const now_epoch = Math.floor(Date.now() / 1000);
            const twentyFourHoursInSeconds = 24 * 60 * 60;
            for (const id in this.masterPlayerData) {
                const player = this.masterPlayerData[id];
                let passesFilter = true;
                if (this.playerFilters.activeOnly) {
                    if (!player.last_login || !(now_epoch - player.last_login < twentyFourHoursInSeconds)) passesFilter = false;
                }
                if (passesFilter && this.playerFilters.privileges.size > 0) {
                    const playerPrivs = new Set(player.privilege ? player.privilege.toLowerCase().split(',') : []);
                    for (const requiredPriv of this.playerFilters.privileges) {
                        if (!playerPrivs.has(requiredPriv)) { passesFilter = false; break; }
                    }
                }
                if (passesFilter) { filteredData[id] = player; }
            }
            const playerListContainer = document.getElementById('player-info-%%current_world_key%%');
            if(playerListContainer) { playerListContainer.innerHTML = this.renderPlayerListHTML(filteredData); }
        },

        init: function() {
            const filterBtn = document.getElementById('player-filter-toggle-btn-%%current_world_key%%');
            const filterDropdown = document.getElementById('player-filter-dropdown-%%current_world_key%%');
            if(filterBtn && filterDropdown) {
                filterBtn.addEventListener('click', (e) => { e.stopPropagation(); filterDropdown.classList.toggle('show'); });
                filterDropdown.addEventListener('change', (e) => {
                    if (e.target.type === 'checkbox') {
                        const filterType = e.target.dataset.filter; const filterValue = e.target.dataset.priv;
                        if(filterType === 'active') { this.playerFilters.activeOnly = e.target.checked; }
                        else if(filterType === 'privilege') { if(e.target.checked) { this.playerFilters.privileges.add(filterValue); } else { this.playerFilters.privileges.delete(filterValue); } }
                        this.applyPlayerFiltersAndRender();
                    }
                });
            }
            window.addEventListener('click', (e) => { if (filterDropdown && filterDropdown.classList.contains('show') && !filterBtn.contains(e.target) && !filterDropdown.contains(e.target)) { filterDropdown.classList.remove('show'); }});
        }
    };
    document.addEventListener('DOMContentLoaded', () => window.playerListLogic_%%current_world_key%%.init());
}
</script>
