{#
/**
 * This file is part of FacturaScripts
 * Copyright (C) 2017-2025 Carlos Garcia Gomez <carlos@facturascripts.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see http://www.gnu.org/licenses/.
 */
#}
{% extends "Master/MenuBghTemplate.html.twig" %}
{% import 'Macro/Utils.html.twig' as Utils %}

{% block bodyHeaderOptions %}
    {{ parent() }}
    <div class="container-fluid mb-2">
        <div class="row">
            <div class="col-sm-6">
                <div class="btn-group">
                    <a class="btn btn-sm btn-secondary" href="{{ fsc.url() }}" title="{{ trans('refresh') }}">
                        <i class="fa-solid fa-redo" aria-hidden="true"></i>
                    </a>
                    {% if fsc.getPageData()['name'] == fsc.user.homepage %}
                        <a class="btn btn-sm btn-secondary active" href="{{ fsc.url() }}?defaultPage=FALSE"
                           title="{{ trans('marked-as-homepage') }}">
                            <i class="fa-solid fa-bookmark" aria-hidden="true"></i>
                        </a>
                    {% else %}
                        <a class="btn btn-sm btn-secondary" href="{{ fsc.url() }}?defaultPage=TRUE"
                           title="{{ trans('mark-as-homepage') }}">
                            <i class="fa-regular fa-bookmark" aria-hidden="true"></i>
                        </a>
                    {% endif %}
                </div>
                {% if config('disable_add_plugins', false) == false %}
                    <button class="btn btn-spin-action btn-sm btn-success" type="button" data-bs-toggle="modal"
                            data-bs-target="#modalAddPlugin">
                        <i class="fa-solid fa-plus fa-fw me-1" aria-hidden="true"></i>
                        <span class="d-none d-sm-inline-block">{{ trans('add') }}</span>
                    </button>
                {% endif %}
                <div class="btn-group">
                    <a href="{{ fsc.url() }}?action=rebuild&multireqtoken={{ formToken(false) }}"
                       onclick="animateSpinner('add')" class="btn btn-spin-action btn-sm btn-warning">
                        <i class="fa-solid fa-hammer fa-fw me-1" aria-hidden="true"></i>
                        <span class="d-none d-sm-inline-block">{{ trans('rebuild') }}</span>
                    </a>
                </div>
            </div>
            <div class="col-sm text-end">
                <h1 class="h3">
                    {{ trans(fsc.getPageData()['title']) | capitalize }}
                    <i class="{{ fsc.getPageData()['icon'] }}" aria-hidden="true"></i>
                </h1>
            </div>
        </div>
    </div>
    <ul class="nav nav-tabs" role="tablist">
        <li class="nav-item">
            <a class="nav-link active" id="installedPluginsTab" data-bs-toggle="tab" href="#installed" role="tab">
                <i class="fa-solid fa-box-open fa-fw" aria-hidden="true"></i> {{ trans('installed-plugins') }}
                {% if fsc.pluginList | length > 0 %}
                    <span class="badge bg-secondary">{{ fsc.pluginList | length }}</span>
                {% endif %}
            </a>
        </li>
        {% if config('disable_add_plugins', false) == false %}
            <li class="nav-item">
                <a class="nav-link" id="allPluginsTab" data-bs-toggle="tab" href="#all" role="tab">
                    <i class="fa-solid fa-boxes fa-fw me-1" aria-hidden="true"></i>
                    <span class="d-none d-sm-inline-block">{{ trans('more-plugins') }}</span>
                    {% if fsc.remotePluginList | length > 0 %}
                        <span class="badge bg-secondary">{{ fsc.remotePluginList | length }}</span>
                    {% endif %}
                </a>
            </li>
        {% endif %}
    </ul>
{% endblock %}

{% block body %}
    {{ parent() }}
    <div class="tab-content">
        <div class="tab-pane fade show active" id="installed" role="tabpanel">
            {{ _self.showInstalledPlugins(fsc) }}
            {% if fsc.updated == false %}
                <div class="ms-2 mt-4 me-2 mb-3">
                    {{ Utils.updateInstall() }}
                </div>
            {% elseif fsc.registered == false %}
                <hr/>
                <div class="ms-2 mt-4 me-2 mb-3">
                    {{ Utils.registerInstall() }}
                </div>
            {% endif %}
        </div>
        {% if config('disable_add_plugins', false) == false %}
            <div class="tab-pane fade" id="all" role="tabpanel">
                {{ _self.showAllPlugins(fsc) }}
            </div>
        {% endif %}
    </div>

    {# Modal for add new plugins #}
    {% if config('disable_add_plugins', false) == false %}
        <form action="{{ fsc.url() }}" class="form" enctype="multipart/form-data" id="f_add_plugins" method="post"
              name="upload-plugins" onsubmit="animateSpinner('add')">
            {{ formToken() }}
            <input type="hidden" name="action" value="upload"/>
            <div class="modal fade" id="modalAddPlugin" tabindex="-1" role="dialog" aria-hidden="true">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title">
                                <i class="fa-solid fa-file-zipper me-2"></i> {{ trans('add-new-plugin') }}
                            </h5>
                            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{{ trans('close') }}"></button>
                        </div>
                        {% if fsc.getMaxFileUpload() < 99 %}
                            <div class="alert alert-dismissible alert-warning mb-0">
                                {{ trans('help-server-accepts-filesize', {'%size%': fsc.getMaxFileUpload()}) }}
                            </div>
                        {% endif %}
                        <div class="modal-body">
                            <div class="mb-3">
                                <label class="form-label">{{ trans('select-plugin-zip-file') }}</label>
                                <input type="file" name="plugin[]" class="form-control" accept="application/zip" multiple required/>
                                {% if fsc.getMaxFileUpload() >= 99 %}
                                    <div class="form-text">
                                        {{ trans('help-server-accepts-filesize', {'%size%': fsc.getMaxFileUpload()}) }}
                                    </div>
                                {% endif %}
                            </div>
                            <div class="text-end mt-5">
                                <button type="button" class="btn btn-spin-action btn-secondary" data-bs-dismiss="modal">
                                    {{ trans('cancel') }}
                                </button>
                                <button type="submit" class="btn btn-spin-action btn-success">
                                    {{ trans('continue') }}
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </form>
    {% endif %}
{% endblock %}

{% block javascripts %}
    {{ parent() }}
    <script>
        // solo se permite activar/desactivar un plugin a la vez
        let pluginActionRunning = false;

        function pluginAction(url, el) {
            if (pluginActionRunning) {
                return false;
            }
            pluginActionRunning = true;

            // bloqueamos el resto de interruptores y botones de la tabla
            document.querySelectorAll('#installed-plugins input, #installed-plugins .btn').forEach(function (item) {
                item.setAttribute('disabled', 'disabled');
                item.classList.add('disabled');
                item.style.pointerEvents = 'none';
            });

            // mostramos un spinner en la celda de estado del plugin pulsado
            const cell = el ? el.closest('td') : null;
            if (cell) {
                cell.innerHTML = '<i class="fa-solid fa-spinner fa-spin fa-lg text-primary" aria-hidden="true"></i>';
            }

            window.location = url;
            return false;
        }
    </script>
    {% if config('disable_rm_plugins', false) == false %}
        <script>
            function deletePlugin(pluginName) {
                // Si ya existe un modal con el ID 'dynamicAdminPluginsDeleteModal', lo eliminamos
                const existingModal = document.getElementById('dynamicAdminPluginsDeleteModal');
                if (existingModal) {
                    existingModal.remove();
                }

                const adminPluginsDeleteCancel = "{{ trans('cancel') }}";
                const adminPluginsDeleteConfirm = "{{ trans('delete') }}";
                const adminPluginsDeleteMessage = "{{ trans('are-you-sure') }}";
                const adminPluginsDeleteTitle = "{{ trans('confirm-delete')|raw }}";

                // Crear el HTML del modal como string usando los parámetros
                const modalHTML = `
                    <div class="modal fade" id="dynamicAdminPluginsDeleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="dynamicAdminPluginsDeleteModalLabel" aria-hidden="true">
                      <div class="modal-dialog">
                        <div class="modal-content">
                          <div class="modal-header">
                            <h5 class="modal-title" id="dynamicAdminPluginsDeleteModalLabel">${adminPluginsDeleteTitle}</h5>
                            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                          </div>
                          <div class="modal-body">
                            ${adminPluginsDeleteMessage}
                          </div>
                          <div class="modal-footer">
                            <button type="button" class="btn btn-secondary btn-spin-action" data-bs-dismiss="modal">${adminPluginsDeleteCancel}</button>
                            <button type="button" id="saveDynamicAdminPluginsDeleteModalBtn" class="btn btn-danger btn-spin-action">${adminPluginsDeleteConfirm}</button>
                          </div>
                        </div>
                      </div>
                    </div>
                  `;

                // Insertar el modal en el body
                document.body.insertAdjacentHTML('beforeend', modalHTML);

                // Crear una instancia del modal y mostrarlo
                const myModal = new bootstrap.Modal(document.getElementById('dynamicAdminPluginsDeleteModal'));
                myModal.show();

                // Añadir comportamiento al botón de "Guardar cambios"
                document.getElementById('saveDynamicAdminPluginsDeleteModalBtn').addEventListener('click', function () {
                    // Ejecutar la acción de eliminar
                    animateSpinner('add');
                    window.location = "{{ fsc.url() }}?action=remove" + "\u0026" + "plugin=" + pluginName
                        + "\u0026" + "multireqtoken={{ formToken(false) }}";

                    // Cierra el modal
                    myModal.hide();
                });

                // Eliminar el modal del DOM cuando se cierra
                document.getElementById('dynamicAdminPluginsDeleteModal').addEventListener('hidden.bs.modal', function () {
                    document.getElementById('dynamicAdminPluginsDeleteModal').remove();
                });
            }

            $(document).ready(function () {
                searchList('#querySearchPlugin', '#all-plugins .wrapper-card', '.card-title, .card-text');
                searchList('#querySearchInstalledPlugins', '#installed-plugins .item-plugin', '.plugin-name, .plugin-description');

                // botones para limpiar los buscadores, visibles solo cuando hay texto
                function setupClearButton(input, button) {
                    const $input = $(input);
                    const $button = $(button);
                    $input.on('input', function () {
                        $button.toggleClass('d-none', this.value.length === 0);
                    });
                    $button.on('click', function () {
                        $input.val('').trigger('keyup').focus();
                        $button.addClass('d-none');
                    });
                }

                setupClearButton('#querySearchInstalledPlugins', '#clearSearchInstalledPlugins');
                setupClearButton('#querySearchPlugin', '#clearSearchPlugin');

                // si los archivos son demasiado grandes, no se pueden subir
                $("#f_add_plugins").submit(function (e) {
                    let size = 0;
                    let files = document.querySelector('input[type=file]').files;
                    for (let i = 0; i < files.length; i++) {
                        size += files[i].size;
                    }

                    if (size > {{ fsc.getMaxFileUpload() }} * 1024 * 1024) { // MB
                        e.preventDefault();
                        alert('{{ trans('plugin-file-too-big', {'%size%': fsc.getMaxFileUpload()}) }}');
                        animateSpinner('remove');
                    }
                });
            });

            function searchList(querySelectorInput, querySelectorItem, querySelectorPluginName) {
                $(querySelectorInput).on('keyup', function (e) {
                    const query = this.value.toLowerCase().trim();
                    $(querySelectorItem).each(function (index, value) {
                        $(value).toggle($(querySelectorPluginName, value).text().toLowerCase().trim().includes(query));
                    });
                });
            }
        </script>
    {% endif %}
{% endblock %}

{% macro healthStatus(value) %}
    {% if value < 1 %}
        <i class="fa-solid fa-heart-broken"></i>
        <i class="fa-regular fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
    {% elseif value < 2 %}
        <i class="fa-solid fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
    {% elseif value < 3 %}
        <i class="fa-solid fa-heart"></i>
        <i class="fa-solid fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
    {% elseif value < 4 %}
        <i class="fa-solid fa-heart"></i>
        <i class="fa-solid fa-heart"></i>
        <i class="fa-solid fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
    {% elseif value < 5 %}
        <i class="fa-solid fa-heart"></i>
        <i class="fa-solid fa-heart"></i>
        <i class="fa-solid fa-heart"></i>
        <i class="fa-solid fa-heart"></i>
        <i class="fa-regular fa-heart"></i>
    {% else %}
        <i class="fa-solid fa-heart"></i>
        <i class="fa-solid fa-heart"></i>
        <i class="fa-solid fa-heart"></i>
        <i class="fa-solid fa-heart"></i>
        <i class="fa-solid fa-heart"></i>
    {% endif %}
{% endmacro %}

{% macro showAllPlugins(fsc) %}
    <div class="p-2">
        <div class="input-group">
            <span class="input-group-text bg-white">
                <i class="fa-solid fa-magnifying-glass text-muted" aria-hidden="true"></i>
            </span>
            <input type="text" class="form-control border-start-0" id="querySearchPlugin"
                   placeholder="{{ trans('search') }}"/>
            <button class="btn btn-outline-secondary d-none" type="button" id="clearSearchPlugin"
                    title="{{ trans('clear') }}">
                <i class="fa-solid fa-xmark" aria-hidden="true"></i>
            </button>
        </div>
    </div>
    <div class="row row-cols-1 row-cols-md-2 row-cols-xl-3 g-2 ps-2 pe-2" id="all-plugins">
        {% for plugin in fsc.remotePluginList %}
            {% set extraClass = plugin.health > 2 ? 'border-success' : plugin.health == 0 ? 'border-danger' : 'border-warning' %}
            <div class="col mb-2 wrapper-card">
                <div class="card {{ extraClass }} shadow-sm h-100" id="{{ plugin.idplugin }}">
                    <div class="card-body p-3">
                        <h5 class="card-title d-flex align-items-start justify-content-between mb-2">
                            <span>{{ plugin.name }}</span>
                            <span class="badge bg-light text-dark border fw-normal ms-2 flex-shrink-0">
                                v{{ plugin.version }}
                            </span>
                        </h5>
                        <p class="card-text text-muted mb-0"
                           style="display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;">
                            {{ plugin.description }}
                        </p>
                    </div>
                    <div class="card-footer p-2 bg-transparent d-flex align-items-center justify-content-between">
                        <a href="{{ plugin.url }}" class="btn btn-sm btn-success" target="_blank">
                            <i class="fa-solid fa-plus fa-fw me-1" aria-hidden="true"></i> {{ trans('add') }}
                        </a>
                        <span class="text-danger small" title="{{ trans('health') }}">
                            {{ _self.healthStatus(plugin.health) }}
                        </span>
                    </div>
                </div>
            </div>
        {% else %}
            <div class="col-12">
                <div class="text-center text-muted p-5">
                    <i class="fa-solid fa-boxes-stacked fa-2x mb-3" aria-hidden="true"></i>
                    <h5>{{ trans('no-data') }}</h5>
                </div>
            </div>
        {% endfor %}
    </div>
{% endmacro %}

{% macro showInstalledPlugins(fsc) %}
    {% set enabledList = fsc.pluginList | filter(plugin => plugin.enabled) | sort((a, b) => a.order <=> b.order) %}
    {% set disabledList = fsc.pluginList | filter(plugin => plugin.enabled == false and plugin.compatible) %}
    {% set incompatibleList = fsc.pluginList | filter(plugin => plugin.enabled == false and plugin.compatible == false) %}
    <div class="m-2 mb-3">
        <div class="input-group">
            <span class="input-group-text bg-white">
                <i class="fa-solid fa-magnifying-glass text-muted" aria-hidden="true"></i>
            </span>
            <input type="text" class="form-control border-start-0" id="querySearchInstalledPlugins"
                   placeholder="{{ trans('search') }}"/>
            <button class="btn btn-outline-secondary d-none" type="button" id="clearSearchInstalledPlugins"
                    title="{{ trans('clear') }}">
                <i class="fa-solid fa-xmark" aria-hidden="true"></i>
            </button>
        </div>
    </div>

    <div class="card m-2 mb-4">
        <div class="table-responsive" id="installed-plugins">
            <table class="table table-hover align-middle mb-0">
                <thead>
                <tr>
                    <th class="text-center">{{ trans('status') }}</th>
                    <th>{{ trans('name') }}</th>
                    <th class="text-end">{{ trans('version') }}</th>
                    <th>{{ trans('description') }}</th>
                    <th class="text-end pe-3">{{ trans('actions') }}</th>
                </tr>
                </thead>
                <tbody>
                {% if enabledList is empty and disabledList is empty and incompatibleList is empty %}
                    <tr class="table-warning">
                        <td colspan="5"><b>{{ trans('no-data') }}</b></td>
                    </tr>
                {% endif %}
                {% if enabledList is not empty %}
                    <tr class="table-success">
                        <td colspan="5" class="fw-bold text-uppercase small">
                            <i class="fa-solid fa-circle-check fa-fw" aria-hidden="true"></i>
                            {{ trans('enabled-plugins') }} <span class="badge bg-success">{{ enabledList | length }}</span>
                        </td>
                    </tr>
                    {% for plugin in enabledList %}
                        {{ _self.pluginRow(plugin, fsc.url()) }}
                    {% endfor %}
                {% endif %}
                {% if disabledList is not empty %}
                    <tr class="table-secondary">
                        <td colspan="5" class="fw-bold text-uppercase small">
                            <i class="fa-regular fa-circle fa-fw" aria-hidden="true"></i>
                            {{ trans('disabled-plugins') }} <span class="badge bg-secondary">{{ disabledList | length }}</span>
                        </td>
                    </tr>
                    {% for plugin in disabledList %}
                        {{ _self.pluginRow(plugin, fsc.url()) }}
                    {% endfor %}
                {% endif %}
                {% if incompatibleList is not empty %}
                    <tr class="table-danger">
                        <td colspan="5" class="fw-bold text-uppercase small">
                            <i class="fa-solid fa-ban fa-fw" aria-hidden="true"></i>
                            {{ trans('incompatible-plugins') }} <span class="badge bg-danger">{{ incompatibleList | length }}</span>
                        </td>
                    </tr>
                    {% for plugin in incompatibleList %}
                        {{ _self.pluginRow(plugin, fsc.url()) }}
                    {% endfor %}
                {% endif %}
                </tbody>
            </table>
        </div>
    </div>
{% endmacro %}

{% macro pluginRow(plugin, url) %}
    <tr class="item-plugin">
        <td class="text-center text-nowrap">
            {% if plugin.enabled %}
                <div class="form-check form-switch d-inline-flex m-0 align-items-center" title="{{ trans('disable') }}">
                    <input class="form-check-input me-0" type="checkbox" role="switch" checked
                           style="cursor: pointer;"
                           onclick="return pluginAction('{{ url }}?action=disable&amp;plugin={{ plugin.name }}&amp;multireqtoken={{ formToken(false) }}', this);">
                </div>
                <div><span class="badge bg-success">{{ trans('active') }}</span></div>
            {% elseif plugin.compatible %}
                <div class="form-check form-switch d-inline-flex m-0 align-items-center" title="{{ trans('enable') }}">
                    <input class="form-check-input me-0" type="checkbox" role="switch"
                           style="cursor: pointer;"
                           onclick="return pluginAction('{{ url }}?action=enable&amp;plugin={{ plugin.name }}&amp;multireqtoken={{ formToken(false) }}', this);">
                </div>
                <div><span class="badge bg-secondary">{{ trans('inactive') }}</span></div>
            {% else %}
                <span class="badge bg-danger" title="{{ plugin.compatibilityDescription() }}">
                    <i class="fa-solid fa-ban me-1" aria-hidden="true"></i>{{ trans('inactive') }}
                </span>
            {% endif %}
        </td>
        <td class="plugin-name">
            {{ plugin.name }}
            {% if plugin.enabled %}
                <br/><small class="text-muted">{{ trans('plugin-order', {'%num%': plugin.order}) }}</small>
            {% endif %}
        </td>
        <td class="text-end">
            {% if plugin.version == 0 %}
                <span class="text-danger">v{{ plugin.version }}</span>
            {% elseif plugin.version < 1 %}
                <span class="text-warning">v{{ plugin.version }}</span>
            {% else %}
                v{{ plugin.version }}
            {% endif %}
        </td>
        <td class="plugin-description">
            {{ plugin.description | nl2br }}
            {% if plugin.forja('url', '') %}
                <a href="{{ plugin.forja('url', '') }}" target="_blank" class="ms-2">
                    {{ trans('more') }} <i class="fa-solid fa-external-link-alt"></i>
                </a>
            {% endif %}
            {% if plugin.compatible == false %}
                <br/><small class="text-danger">{{ plugin.compatibilityDescription() }}</small>
            {% endif %}
            {% for requiredPluginName in plugin.require %}
                <br/>
                <div class="badge bg-secondary">
                    {{ trans('plugin-needed', {'%pluginName%': requiredPluginName}) }}
                </div>
            {% endfor %}
        </td>
        <td class="text-end text-nowrap">
            {% if plugin.hasUpdate() %}
                <a href="Updater" class="btn btn-spin-action btn-sm btn-info" title="{{ trans('update') }}">
                    <i class="fa-solid fa-cloud-download-alt me-1" aria-hidden="true"></i>
                    <span class="d-none d-sm-inline-block">{{ trans('update') }}</span>
                </a>
            {% endif %}
            {% if plugin.enabled == false and config('disable_rm_plugins', false) == false %}
                <a class="btn btn-sm btn-danger btn-spin-action" href="#"
                   title="{{ trans('delete') }}" onclick="deletePlugin('{{ plugin.name }}');">
                    <i class="fa-solid fa-trash-alt" aria-hidden="true"></i>
                </a>
            {% endif %}
        </td>
    </tr>
{% endmacro %}