{{@include("header", it)/}}


<style>
    /* Chart stuff */
    #d3-container {
        height: 340px;
        margin: auto;
        overflow: hidden;
        /* DEBUG */
        /* background-color: rgb(207, 233, 255);  */
    }
    #d3-container svg {
        height: 340px;
        width: 100%;
        margin: auto;
        overflow: hidden;
    }
    #x-axis path{
        stroke: none;
        fill: none;
    }
    #tickBucketsAxis path,
    #tickBucketsAxis line {
        stroke: none;
        fill: none;
    }
    .axis {
        color: dimgrey;
    }
    .axisTitle {
        color: dimgrey;
        font-size: 16px;
        font-weight: 500;
    }
    .axisTitle .tickTimeLabel{
        min-width: 2em;
        height: 18px;
        border: dimgrey 2px solid;
        background: rgb(35,23,27);
        /* background: linear-gradient(90deg, rgba(35,23,27,1) 10%, rgba(45,161,243,1) 35%, rgba(69,246,139,1) 65%, rgba(224,69,19,1) 90%); */
        background: linear-gradient(90deg, #482475 10%, #2f6c8e 35%, #2fb47c 65%, #bddf26 90%);
    }
    .axisTitle .clientsLabel{
        min-width: 2em;
        height: 18px;
        border: dimgrey 2px solid;
        background: rgb(204, 203, 203);
    }

    /* Other stuff */
    #status-card{
        font-size: 1.15rem;
        font-weight: 500;
        line-height: 2;
    }

    .dashboard-chart {
        width: 100% !important; 
        max-width: 890px !important;
    }
</style>

<!-- Title & outdated message: -->
<div class="text-center mb-4">
    <h2>{{it.serverName}} Dashboard</h2>
    {{@if(it.txAdminOutdated)}}
        <h2 class="text-danger">This version of txAdmin is outdated. Please update now.</h2>
        <h5 class="text-muted">
            Updating is <i>very</i> easy! Support Discord:
            <a href="https://discord.gg/uAmsGa2" target="_blank" style="vertical-align: text-bottom;">
                <img src="https://discordapp.com/api/guilds/577993482761928734/widget.png?style=shield"></img>
            </a>
        </h5>
    {{/if}}
</div>


<!-- Chart stuff -->
<div class="row justify-content-center">
    <div class="dashboard-chart">
        <div class="card card-accent-info">
            <div class="card-body p-1">
                <div class="text-center axisTitle">
                    <!-- <span class="clientsLabel">■</span> -->
                    <span class="badge clientsLabel"> &nbsp; </span>
                    Players
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    <!-- <span class="tickTimeLabel">■</span> -->
                    <span class="badge tickTimeLabel"> &nbsp; </span>
                    Tick Time (lower is better)
                </div>
                
                <div id="d3-container">
                    <br><br><br><br><br>
                    <div class="text-center text-muted p-4" style="font-size: 2.25em;" id="d3-container-message">
                        loading chart...
                    </div>
                </div>
            
            </div>
        </div>
    </div>
</div>



<div class="row justify-content-center">
    <!-- Server Control -->
    <div class="col-lg-8 col-xl-6 dashboard-card mw-col6">
        <div class="card card-accent-danger" style="min-height: 200px;">
            <div class="card-header text-center">
                <h5 class="d-inline">Server Control</h5>
            </div>
            <div class="card-body text-center align-middle">
                <button onclick="controlAction('start')"
                    class="btn btn-outline-{{it.perms.controlsClass}} btn-lg mx-auto m-2" type="button" id="ctrl-start"
                    {{it.perms.controls}}>START</button> &nbsp;
                <button onclick="controlAction('restart')"
                    class="btn btn-outline-{{it.perms.controlsClass}} btn-lg mx-auto m-2" type="button"
                    id="ctrl-restart" {{it.perms.controls}}>RESTART</button> &nbsp;
                <button onclick="controlAction('stop')"
                    class="btn btn-outline-{{it.perms.controlsClass}} btn-lg mx-auto m-2" type="button" id="ctrl-stop"
                    {{it.perms.controls}}>STOP</button>
                <br>

                <button onclick="controlCommand('admin_broadcast')" class="btn btn-outline-dark btn-md mx-auto m-2"
                    type="button" id="ctrl-stop" {{it.perms.commandMessage}}>Announcement</button> &nbsp;
                <button onclick="controlCommand('kick_all')" class="btn btn-outline-dark btn-md mx-auto m-2"
                    type="button" id="ctrl-stop" {{it.perms.commandKick}}>Kick All Players</button>
            </div>
        </div>
    </div>

    <!-- Status Info-->
    <div class="col-lg-8 col-xl-6 dashboard-card mw-col6">
        <div class="card card-accent-danger" style="min-height: 200px;">
            <div class="card-header text-center">
                <h5 class="d-inline">Status Info</h5>
            </div>
            <div class="card-body" id="status-card">
                <br>
                <div class="text-center">
                    Loading...
                </div>
            </div>
        </div>
    </div>

</div>


<!-- Benchmark, update, pre-release messages -->
<div class="row justify-content-md-center">
    <div class="col-md-6 text-center">
        <small id="perfDiagnosticsMessage" class="text-muted"></small>
        <br>
        {{@if(it.versionData.message)}}
            <div class="alert alert-{{it.versionData.color}} border-{{it.versionData.color}}" role="alert">
                <a href="{{it.versionData.artifactsLink}}" target="_blank" class="alert-link">{{it.versionData.message}}</a>
                <br>
                {{it.versionData.subtext}}
            </div>
        {{/if}}
        {{@if(it.txAdminVersion.includes('-'))}}
            <span class="text-danger font-weight-bold">
                You are using a pre-release version of txAdmin destined for developers and beta testers only! <br>
                Your server stability might be impacted by this.
            </span>
        {{/if}}
    </div>
</div>


{{@include("footer", it)/}}

<script src="https://d3js.org/d3.v6.min.js"></script>
<script type="module">
    import { drawHeatmap } from "/js/txadmin/chart.js";

    //Elements
    const perfDiagnosticsMessage = document.getElementById('perfDiagnosticsMessage');
    const d3Container = document.getElementById('d3-container');
    const d3ContainerMessage = document.getElementById('d3-container-message');
    
    (async () => {
        //Prepare data
        let perfData;
        try {
            const rawPerfData = await fetch(`/chartData`);
            const parsedPerfData = JSON.parse(await rawPerfData.text());
            if(!Array.isArray(parsedPerfData)){
                if(parsedPerfData.failReason == 'not_set'){
                    d3ContainerMessage.innerText = 'chart database still loading';

                }else if(parsedPerfData.failReason == 'not_enough_data'){
                    d3ContainerMessage.innerText = 'Players & Performance data will be available soon...';

                }else if(parsedPerfData.failReason == 'data_processing'){
                    d3ContainerMessage.innerText = 'chart data processing failed';

                }else{
                    d3ContainerMessage.innerText = 'invalid chart data';

                }
            }else{
                perfData = parsedPerfData;
            }
        } catch (error) {
            d3ContainerMessage.innerText = 'failed to load chart data';
        }
        if(!perfData) return;
        //DEBUG
        // perfData = [...perfData, ...perfData, ...perfData]
        // perfData = perfData.slice(-50)

        //Render page
        const chartOptions = {
            // colorScheme: d3[`{{[it.uiTheme, 'interpolateViridis', 'interpolateTurbo']|ternary}}`],
            // colorScheme: d3.interpolateInferno,
            // colorScheme: d3.interpolateTurbo,
            colorScheme: d3.interpolateViridis,
        }

        const draw = () => {
            const tsStart = Date.now();
            drawHeatmap(d3Container, perfData, chartOptions);
            d3Container.style.opacity = 1;
            const duration = Date.now() - tsStart;
            perfDiagnosticsMessage.textContent = `Took ${duration}ms to draw ${perfData.length*15} rects from ${perfData.length} snapshots.`;
        }
        draw();

        let redrawTimeout;
        window.addEventListener("resize", () => {
            clearTimeout(redrawTimeout);
            d3Container.style.opacity = 0.5;
            redrawTimeout = setTimeout(() => {
                draw();
            }, 250);
        });
    })();
</script>

<script>
    //============================================== Controls (start/restart/stop)
    function controlAction(action) {
        if (action !== 'start' && !window.confirm('Are you sure you want to ' + action + ' the server?')) {
            return;
        }
        var notify = $.notify({ message: '<p class="text-center">Executing Command...</p>' }, {});
        $.ajax({
            url: '/fxserver/controls/' + action,
            type: "GET",
            dataType: "json",
            timeout: timeoutLong,
            success: function (data) {
                if (data.logout) {
                    window.location = '/auth?logout';
                    return;
                }
                notify.update('progress', 0);
                notify.update('type', data.type);
                notify.update('message', data.message);
            },
            error: function (xmlhttprequest, textstatus, message) {
                notify.update('progress', 0);
                notify.update('type', 'danger');
                notify.update('message', message);
            }
        });
    }


    //============================================== Commands
    function controlCommand(action) {
        let message = null;
        if(action == 'admin_broadcast'){
            message = prompt('Type the message to be broadcasted to all players');
            if(message.length <= 6){
                $.notify({ message: 'This message is too short!'}, {type: 'danger'});
                return;
            }
        }else if(action == 'kick_all'){
            message = prompt('Type the kick reason or leave it blank (press enter)');
        }else{
            return;
        }
        if(message == null) return;

        var notify = $.notify({ message: 'Executing Command...' }, {});
        $.ajax({
            type: "POST",
            url: '/fxserver/commands',
            timeout: timeoutMedium,
            data: {
                action,
                parameter: message
            },
            success: function (data) {
                notify.update('progress', 0);
                notify.update('type', data.type);
                notify.update('message', data.message);
            },
            error: function (xmlhttprequest, textstatus, message) {
                notify.update('progress', 0);
                notify.update('type', 'danger');
                notify.update('message', message);
            }
        });
    }
</script>
