<%- await include('parts/header.ejs', locals) %>

<style>
    .console-content {
        height: calc(100vh - 378px);
        margin: 0;
    }

    .nui-height{
        height: calc(100vh - 230px);
    }

    .console-input {
        max-width: 24rem !important;
        width: 100% !important;
        margin-bottom: 1em;
    }

    #cmdHistoryDiv{
        display: inline-block;
    }

    @media (max-width: 1200px) {
        #cmdHistoryDiv{
            text-align: center!important;
        }
    }

    /* Custom Scrollbar colors for dark console */
    .console-content::-webkit-scrollbar-track {
        background-color: #1E252D;
        border-right: 1px solid #1E252D;
        border-left: 1px solid #1E252D;
    }

    .console-content::-webkit-scrollbar-thumb {
        background-color: #565C62;
    }

    .console-content::-webkit-scrollbar-corner {
        background: #1E252D;
    }

    .bg-dark {
        background-color: #252E38 !important;
    }

    .command-history {
        line-height: 2rem;
        display: inline-block;
    }

    .command-history > button {
        background-color: transparent !important;
        color: #768192 !important;
        border: 1px solid #768192;
    }

    .command-history > button:hover {
        background-color: transparent !important;
        color: rgb(183, 189, 199)!important;
        border: 1px solid rgb(183, 189, 199);
    }
</style>


<div class="card bg-dark">
    <div class="p-3" style="position: relative">
        <pre id="console" class="thin-scroll console-content text-white <%= (isWebInterface ? '' : 'nui-height') %>"></pre>
        <div id="autoScrollDiv">
            <a id="autoScrollBtn" class="d-none" href="#"><span></span><span></span><span></span></a>
        </div>
    </div>
    <div class="card-footer bg-dark">
        <div class="row">
            <div class="col-xl-6 col-lg-12">
                <form class="form-inline container-fluid text-center" id="frmConsole">
                    <input type="text" class="form-control console-input form-control-sm" id="cmdInput"
                        placeholder="Press enter to send. Up/Down arrows to navigate commands."
                        autocomplete="off" autocorrect="off" autocapitalize="off"
                        spellcheck="false" style="width: 100%" <%= disableCommand %>
                    />
                    &nbsp;
                    <a href="fxserver/downloadLog" target="_blank" 
                        class="btn btn-outline-light btn-sm mb-2 <%= (isWebInterface ? '' : 'disabled') %>">
                        Download Log
                    </a>
                    &nbsp;
                    <button type="button" id="clearConsole" class="btn btn-outline-light btn-sm mb-2">
                        Clear Console
                    </button>
                </form>
            </div>
            <div class="col-xl-6 col-lg-12" id="cmdHistoryDiv">
                <span class="text-light font-weight-bold">History:</span> <small class="text-muted">(click to copy)</small><br>
                <div class="command-history" id="cmdHistory"></div>
            </div>
        </div>

    </div>
</div>

<!-- continuity warning -->
<div class="row justify-content-md-center">
    <div class="col-md-6 text-center">
        <span class="text-warning font-weight-bold">
            This legacy Live Console page is only still available during this Beta2 phase in case something breaks in the new one. It will be removed for the txAdmin v7.0.0 release.
        </span>
    </div>
</div>


<%- await include('parts/footer.ejs', locals) %>


<script src="js/ansi_up.js?txVer=<%= txAdminVersion %>"></script>
<script>
    //============================================== Live Console stuff
    (function () {
        //Preparing variables
        const BUFFER_TRIM_SIZE = 128 * 1024; // 128kb
        const commandHistoryLimit = 12;
        
        const ansi_up = new AnsiUp;
        ansi_up.escape_for_html = false;
        const input = document.getElementById("cmdInput");
        const consoleElement = document.getElementById("console");
        const consoleForm = document.getElementById("frmConsole");
        const historyDiv = document.getElementById('cmdHistoryDiv');
        const historyElement = document.getElementById('cmdHistory');
        const autoScrollBtn = document.getElementById("autoScrollBtn");
        let commandHistory = [];
        let commandCache = [];
        let autoScroll = true;
        let arrowHistIndex;
    

        //Helper Functions
        const stringToDOMId = (str) => `${str.replace(/\s?\s+/g, '-').slice(0, 32)}${str.length > 32 ? '_trim' : ''}`.trim();

        const setInputValue = (newValue) => {
            input.value = newValue;
            input.focus();
        }

        const addCommandHistoryEntry = (command) => {
            const btnText = `${command.slice(0, 15)}${command.length > 15 ? '...' : ''}`;
            const node = document.createElement('button');
            node.appendChild(document.createTextNode(btnText));
            node.setAttribute('id', stringToDOMId(command));
            node.setAttribute('class', 'btn btn-outline-light btn-sm m-1');
            node.setAttribute('title', command);
            node.onclick = (e) => {
                setInputValue(command);
            };
            historyElement.appendChild(node);
        }

        const scrollBottom = () => {
            if (autoScroll) consoleElement.scrollTop = consoleElement.scrollHeight;
        }

        const autoscrollToggle = (status) => {
            autoScroll = status
            if(autoScroll){
                autoScrollBtn.classList.add('d-none');
            }else{
                autoScrollBtn.classList.remove('d-none');
            }
            scrollBottom();
        }

        // Load command history from local storage
        if(typeof window.localStorage.liveConsoleCommandHistoryOld !== 'undefined'){
            try {
                const fromStorage = JSON.parse(window.localStorage.liveConsoleCommandHistoryOld);
                commandHistory = fromStorage.slice(0 - commandHistoryLimit);
                commandHistory.forEach(addCommandHistoryEntry);
            } catch (error) {
                console.error('Failed to process window.localStorage.liveConsoleCommandHistoryOld');
            }
        }

        
        //Socket stuff
        const pageSocket = getSocket('liveconsole');
        pageSocket.on('error', (error) => {
            console.log('Page Socket.IO', error);
        });
        pageSocket.on('connect', () => {
            console.log("Page Socket.IO Connected.");
        });
        pageSocket.on('disconnect', (message) => {
            console.log("Page Socket.IO Disonnected:", message);
        });
        pageSocket.on('consoleData', function (msg) {
            const cleanMsg = xss(msg)
                .replace(/<br>/g, '\n')
                .replace(/{txMarker-(\w+)}/g, '<mark class="consoleMark-$1">')
                .replace(/{\/txMarker}/g, '</mark>');

            let _consoleData = consoleElement.innerHTML + ansi_up.ansi_to_html(cleanMsg);
            _consoleData = (_consoleData.length > BUFFER_TRIM_SIZE)
                ? _consoleData.slice(-0.5 * BUFFER_TRIM_SIZE) // grab the last half
                : _consoleData; // no need to trim
            consoleElement.innerHTML = _consoleData.substr(_consoleData.indexOf("\n"));

            scrollBottom();
        });

        consoleElement.addEventListener('scroll',function(){
                const scrollTop = consoleElement.scrollTop;
                const scrollHeight = consoleElement.scrollHeight;
                const offsetHeight = consoleElement.offsetHeight;
                const contentHeight = scrollHeight - offsetHeight;
                if (scrollTop < contentHeight) {
                    autoscrollToggle(false);
                } else if(scrollTop === contentHeight){
                    autoscrollToggle(true);
                }
            }
        )


        //Form
        consoleForm.addEventListener("submit", function (e) {
            e.preventDefault();
            const command = input.value.trim();
            setInputValue('');
            if(!command.length) return;
            arrowHistIndex = -1;

            commandCache.unshift(command);
            pageSocket.emit('consoleCommand', command);

            autoscrollToggle(true);

            if(!commandHistory.includes(command)){
                addCommandHistoryEntry(command);
                commandHistory.push(command); //DEBUG valueToPush?
                // truncation
                if (commandHistory.length >= commandHistoryLimit) {
                    const search = commandHistory.find((_, index) => index === (commandHistory.length - commandHistoryLimit));
                    const element = document.getElementById(stringToDOMId(search));
                    element.remove();
                    commandHistory.shift();
                }
                window.localStorage.liveConsoleCommandHistoryOld = JSON.stringify(commandHistory);
            }
        });


        //Up / Down history
        input.addEventListener("keydown", function (event) {
            let changed = false;

            if (event.key === "ArrowUp") {
                event.preventDefault();
                changed = true;
                if (typeof arrowHistIndex === 'undefined' && commandCache.length > 0) {
                    arrowHistIndex = 0;
                } else if ((arrowHistIndex + 1) < commandCache.length) {
                    arrowHistIndex += 1;
                }

            } else if (event.key === "ArrowDown") {
                event.preventDefault();
                changed = true;
                if (arrowHistIndex > 0) {
                    arrowHistIndex -= 1;
                } else if (arrowHistIndex === 0) {
                    arrowHistIndex = undefined;
                }
            }

            if (changed) setInputValue(commandCache[arrowHistIndex] || '');
        });

        //Buttons
        autoScrollBtn.addEventListener("click", (event) => {
            event.preventDefault();
            autoscrollToggle(true);
        });

        document.getElementById("clearConsole").addEventListener("click", function () {
            consoleElement.innerHTML = "Console cleared.<br />\n";
        });
    })();
</script>
