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

<style>
    .collapsed {
        height: 0;
    }
    .head-hover:hover {
        cursor: pointer;
        text-decoration: underline;
        text-decoration-color: #d8dbe0;
    }
    .fix-pill-form {
        min-width: 65px;
    }
</style>

<div class="row justify-content-center">
    <div class="col-md-8 mw-col6">
        <div class="card card-accent-info">
            <div class="card-body py-3">
                <input
                    class="form-control my-1"
                    type="text"
                    name="resource"
                    id="resourceInput"
                    onkeyup="findResource()"
                    placeholder="Find resource by name..."
                >
                <div class="d-flex flex-wrap justify-content-xs-center justify-content-between pt-2" style="gap: 1rem;">
                    <div class="d-flex flex-grow-1x" style="gap: 1rem;">
                        <div class="d-flex flex-column flex-lg-row align-items-center" style="gap: 0.5rem;">
                            <span class="form-text text-muted text-center">
                                Default resources:
                            </span>
                            <label class="switch-lg c-switch c-switch-label c-switch-pill c-switch-success fix-pill-form">
                                <input type="checkbox" id="defResCheckbox" class="c-switch-input">
                                <span class="c-switch-slider" data-checked="Show" data-unchecked="Hide"></span>
                            </label>
                        </div>
                        
                        <div class="d-flex flex-column flex-lg-row align-items-center" style="gap: 0.5rem;">
                            <span class="form-text text-muted text-center">
                                Only stopped resources:
                            </span>
                            <label class="switch-lg c-switch c-switch-label c-switch-pill c-switch-success fix-pill-form">
                                <input type="checkbox" id="stoppedResCheckbox" class="c-switch-input">
                                <span class="c-switch-slider" data-checked="Show" data-unchecked="Hide"></span>
                            </label>
                        </div>
                    </div>
                    
                    <div class="d-flex" style="gap: 0.75rem;">
                        <button 
                            class="btn btn-sm btn-outline-secondary float-right" 
                            type="button"
                            id="btnExpandCollapse"
                        />
                        <button class="btn btn-sm btn-primary float-right" type="button" id="btnRefresh" <%= disableActions %>>
                            <i class="icon-refresh"></i> Reload & Refresh
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div class="row justify-content-center">
    <div class="col-sm-12 col-lg-8 mw-col8">
        <% for (const resGroup of resGroups) { %>
            <div class="card table-responsive-sm" style="margin: 1em 0; border-radius: 0;" id="resList-card-<%= resGroup.divName %>">
                <!-- Table class is responsible for the sharper edges -->
                <table class="table table-hover table-outline mb-0">
                    <thead class="thead-light head-hover">
                        <tr>
                            <th class="text-break text-center" colspan="2">
                                <%= resGroup.subPath %>
                                <span class="toggle-icon" id="icon-<%= resGroup.divName %>">
                                    <i class="icon-arrow-down" style="font-size: 75%; font-weight: bold;"></i>
                                </span>
                            </th>
                        </tr>
                    </thead>
                    <tbody id="resList-cardBody-<%= resGroup.divName %>" aria-labelledby="resList-cardHeader-<%= resGroup.divName %>" class="mb-1">
                        <% for (const resource of resGroup.resources) { %>
                            <tr id="res-<%= resource.divName %>">
                                <td>
                                    <strong style="word-wrap: break-word;"><%= resource.name %></strong>
                                    <% if (resource.version !== '') { %>
                                        <em><%= resource.version %></em>
                                    <% } %>
                                    <% if (resource.author !== '') { %>
                                        by <%= resource.author %>
                                    <% } %>
                                    <% if (resource.description !== '') { %>
                                        <br/>
                                        <%= resource.description %>
                                    <% } %>
                                </td>
                                <td class="tableActions">
                                    <% if (resource.status === 'started') { %>
                                    <a class="btn-res-action btn btn-sm btn-outline-warning d-block d-md-inline-block mr-md-1 mb-1 mb-md-0 <%= disableActions %>"
                                        href="#"
                                        data-resAction="ensure_res"
                                        data-resName="<%= encodeURIComponent(resource.name) %>"
                                        <%= disableActions %>
                                    >
                                        Restart
                                    </a>
                                    <a class="btn-res-action btn btn-sm btn-outline-danger d-block d-md-inline-block m-0 <%= disableActions %>"
                                        href="#"
                                        data-resAction="stop_res"
                                        data-resName="<%= encodeURIComponent(resource.name) %>"
                                        <%= disableActions %>
                                    >
                                        Stop
                                    </a>
                                    <% } else { %>
                                    <a class="btn-res-action btn btn-sm btn-outline-success d-block d-md-inline-block <%= disableActions %>"
                                        href="#"
                                        data-resAction="ensure_res"
                                        data-resName="<%= encodeURIComponent(resource.name) %>"
                                        <%= disableActions %>
                                    >
                                        Start
                                    </a>
                                    <% } %>
                                </td>
                            </tr>
                        <% } %>
                    </tbody>
                </table>
            </div>
        <% } %>
    </div>
</div>


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




<script>
    //NOTE: this is hacky af, but whatever
    const resGroupsJS = JSON.parse(atob(`<%= (Buffer.from(resGroupsJS).toString('base64')) %>`));
    
    const defaultResources = [
        "baseevents",
        "basic-gamemode",
        "betaguns", //old
        "channelfeed", //old
        "chat-theme-gtao",
        "chat",
        "example-loadscreen",
        "fivem-awesome1501", //old
        "fivem-map-hipster",
        "fivem-map-skater",
        "fivem",
        "gameInit", //old
        "hardcap",
        "irc", //old
        "keks", //old
        "mapmanager",
        "money-fountain-example-map",
        "money-fountain",
        "money",
        "monitor",
        "obituary-deaths", //old
        "obituary", //old
        "ped-money-drops",
        "player-data",
        "playernames",
        "race-test", //old
        "race", //old
        "rconlog",
        "redm-map-one",
        "runcode",
        "scoreboard",
        "sessionmanager-rdr3",
        "sessionmanager",
        "spawnmanager",
        "webadmin",
        "webpack",
        "yarn",
    ]

    const convErrorType = (x) => x === 'error' ? 'danger' : x;

    //============================================== Page State
    let collapsedGroups = new Set();
    try {
        const storedCollapsedGroups = window.localStorage.resourcesPageCollapsedGroups;
        if (storedCollapsedGroups) {
            const parsedCollapsedGroups = JSON.parse(storedCollapsedGroups);
            if (Array.isArray(parsedCollapsedGroups)) {
                collapsedGroups = new Set(parsedCollapsedGroups);
            } else {
                throw new Error('Invalid storedCollapsedGroups');
            }
        } else {
            window.localStorage.resourcesPageCollapsedGroups = '[]';
        }
    } catch (error) {
        console.warn('Error parsing storedCollapsedGroups:', error);
        window.localStorage.resourcesPageCollapsedGroups = '[]';
    }
    const saveCollapsedGroups = () => {
        window.localStorage.resourcesPageCollapsedGroups = JSON.stringify([...collapsedGroups.values()]);
    }
    

    $('#defResCheckbox').click(() => {
        window.localStorage.resourcesPageShowDefault = document.getElementById('defResCheckbox').checked;
        refreshResourceList();
    });

    $('#stoppedResCheckbox').click(() => {
        window.localStorage.resourcesPageShowStopped = document.getElementById('stoppedResCheckbox').checked;
        refreshResourceList();
    });


    //============================================== Refresh List
    $('#btnRefresh').click(() => {
        const notify = $.notify({ message: '<p class="text-center">Executing Command...</p>' }, {});
        txAdminAPI({
            type: "POST",
            url: '/fxserver/commands',
            timeout: REQ_TIMEOUT_LONG,
            data: { action: 'refresh_res', parameter: '' },
            success: function (data) {
                if(data.type !== 'error'){
                    window.location.reload(true);
                }else{
                    notify.update('progress', 0);
                    notify.update('type', convErrorType(data.type));
                    notify.update('message', data.msg);
                }
            },
            error: function (xmlhttprequest, textstatus, message) {
                notify.update('progress', 0);
                notify.update('type', 'danger');
                notify.update('message', message);
            }
        });
    })


    //============================================== Start/Stop/Restart buttons
    function btnCommand(action, parameter) {
        const notify = $.notify({ message: '<p class="text-center">Executing Command...</p>' }, {});
        txAdminAPI({
            type: "POST",
            url: '/fxserver/commands',
            data: { action, parameter },
            success: function (data) {
                if(data.type !== 'error'){
                    window.location.reload(true);
                }else{
                    notify.update('progress', 0);
                    notify.update('type', convErrorType(data.type));
                    notify.update('message', data.msg);
                }
            },
            error: function (xmlhttprequest, textstatus, message) {
                notify.update('progress', 0);
                notify.update('type', 'danger');
                notify.update('message', message);
            }
        });
    }

    //============================================== Search function
    function findResource() {
        const inputEl = document.getElementById("resourceInput");
        localStorage.setItem("resourcesPageFilter", inputEl.value ?? '');
        const filter = inputEl.value.toUpperCase();

        resGroupsJS.forEach(folder => {
            let hidden = 0;
            folder.resources.forEach(resource => {
                if (resource.name.toUpperCase().indexOf(filter) > -1) {
                    $(`#res-${resource.divName}`).show();
                } else {
                    hidden++;
                    $(`#res-${resource.divName}`).hide();
                }
            });
            if (folder.resources.length == hidden) {
                $(`#resList-card-${folder.divName}`).hide();
            } else {
                $(`#resList-card-${folder.divName}`).show();
            }
        });
        if(!filter.length){
            refreshResourceList();
        }
    }

    //============================================== Expand/Collapse All
    let isExpandButton = false;
    const btnExpandCollapse = document.getElementById('btnExpandCollapse');
    const btnExpandCollapseIcon = btnExpandCollapse.querySelector('i');
    function updateExpandCollapseBtn() {
        let expandedCount = 0;
        let collapsedCount = 0;
        resGroupsJS.forEach(folder => {
            const card = document.getElementById(`resList-card-${folder.divName}`);
            if (card.querySelector('tbody').classList.contains('collapse')) {
                collapsedCount++;
            } else {
                expandedCount++;
            }
        });
        if (expandedCount === resGroupsJS.length) {
            isExpandButton = false;
            btnExpandCollapse.innerHTML = '<i class="icon-size-actual"></i> Collapse All';
        } else {
            isExpandButton = true;
            btnExpandCollapse.innerHTML = '<i class="icon-size-fullscreen"></i> Expand All';
        }
    }
    $('#btnExpandCollapse').click(() => {
        if (isExpandButton) {
            resGroupsJS.forEach(folder => {
                const card = document.getElementById(`resList-card-${folder.divName}`);
                toggleResGroup(card, false, true);
            });
        } else {
            resGroupsJS.forEach(folder => {
                const card = document.getElementById(`resList-card-${folder.divName}`);
                toggleResGroup(card, false, false);
            });
        }
        updateExpandCollapseBtn();
    })

    //============================================== Utils
    function refreshResourceList() {
        const resButtons = document.getElementsByClassName('btn-res-action');
        for (const btn of resButtons) {
            btn.onclick = (e) => {
                e.preventDefault();
                const resAction = e.currentTarget.dataset.resaction;
                const resName = decodeURIComponent(e.currentTarget.dataset.resname);
                btnCommand(resAction, resName);
            };
        }

        if ($('#defResCheckbox').is(':checked')) {
            defaultResources.forEach(defRes => {
                $(`#res-${defRes}`).show();
                $(`#res-${defRes}`).removeClass("defaultRes");

                $(`#res-${defRes}`).closest('div').show();
            })
        } else {
            defaultResources.forEach(defRes => {
                const trElement = $(`#res-${defRes}`);

                trElement.hide();
                trElement.addClass("defaultRes");

                $(`#res-${defRes}`).closest('div').hide();
            })
        }

        const onlyStopped = $('#stoppedResCheckbox').is(':checked')
        resGroupsJS.forEach(folder => {
            let hidden = 0;

            folder.resources.forEach(resource => {
                if ($(`#res-${resource.divName}`).hasClass("defaultRes")) {
                    hidden++;
                    return
                }

                if (onlyStopped && resource.status !== 'stopped') {
                    $(`#res-${resource.divName}`).hide()
                    hidden++;
                } else {
                    $(`#res-${resource.divName}`).show()
                }
            });

            const card = $(`#resList-card-${folder.divName}`);
            if (folder.resources.length === hidden) {
                card.hide();
            } else {
                card.show();
            }
            if (collapsedGroups.has(folder.divName)) {
                toggleResGroup(card[0], false, false);
            } else {
                toggleResGroup(card[0], false, true);
            }
        });
    }


    function toggleResGroup(groupCardElement, single, show) {
        const tbody = groupCardElement.querySelector("tbody");
        const icon = groupCardElement.querySelector('.toggle-icon i');
        if (show === undefined) {
            show = tbody.classList.contains('collapse');
        }
        const groupDivName = groupCardElement.id.split('-').pop();
        if (show) {
            tbody.classList.remove('collapse');
            icon.classList.remove('icon-arrow-down');
            icon.classList.add('icon-arrow-up');
            if (single) {
                groupCardElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
            }
            collapsedGroups.delete(groupDivName);
        } else {
            tbody.classList.add('collapse');
            icon.classList.add('icon-arrow-down');
            icon.classList.remove('icon-arrow-up');
            collapsedGroups.add(groupDivName);
        }
        saveCollapsedGroups();
    }

    $(() => {
        if (typeof window.localStorage.resourcesPageShowDefault === 'string') {
            document.getElementById('defResCheckbox').checked = (window.localStorage.resourcesPageShowDefault === 'true');
        } else {
            window.localStorage.resourcesPageShowDefault = false;
        }
        let hasFilter = false;
        if (typeof window.localStorage.resourcesPageFilter === 'string' && window.localStorage.resourcesPageFilter.length) {
            document.getElementById("resourceInput").value = window.localStorage.resourcesPageFilter;
            hasFilter = true;
        }

        document.getElementById('stoppedResCheckbox').checked = window.localStorage.resourcesPageShowStopped === 'true';

        //Make the theads clickable
        resGroupsJS.forEach(folder => {
            const card = document.getElementById(`resList-card-${folder.divName}`);
            const thead = card.querySelector('thead');
            thead.addEventListener('click', () => {
                toggleResGroup(card, true);
                updateExpandCollapseBtn();
            });
        });

        refreshResourceList();
        updateExpandCollapseBtn();
        if(hasFilter){
            findResource();
        }
    });
</script>
