{* Admin Web settings tab — mirrors client-area web_settings.tpl but
   targets the admin AJAX endpoints (no allow_* gating; restore_lock
   still honoured server-side). Three controls: PHP version (dropdown +
   Apply), HTTPS redirect (toggle + Apply), Proxy extensions (textarea +
   Apply / Defaults / Disable). *}
<style>
.puq-ws-row { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.puq-ws-row > .puq-ws-status { min-width:18px; display:inline-block; }
.puq-ws-row > select, .puq-ws-row > textarea { max-width:520px; }
.puq-ws-section { padding:12px 14px; background:#fff; border:1px solid #ddd; border-radius:3px; margin-bottom:12px; }
.puq-ws-section h4 { margin:0 0 10px; font-size:14px; font-weight:600; }
.puq-ws-help { color:#777; font-size:11px; margin:6px 0 0; }
.puq-ws-lock-banner { padding:8px 12px; background:#fff3cd; border:1px solid #ffeeba; color:#856404; border-radius:3px; margin-bottom:12px; font-size:12px; }
</style>

<div id="puq-ws-state" class="puq-tab-loading"><i class="fa fa-spinner fa-spin"></i> Loading Web settings…</div>

<div id="puq-ws-body" style="display:none;">
    <div id="puq-ws-lock" class="puq-ws-lock-banner" style="display:none;">
        <i class="fa fa-lock"></i> Web role is currently being restored from backup — settings are temporarily read-only.
    </div>

    <div class="puq-ws-section">
        <h4><i class="fab fa-php" style="color:#777bb4;"></i> PHP version</h4>
        <div class="puq-ws-row">
            <select id="puq-ws-php-select" class="form-control input-sm" style="width:auto;min-width:200px;"></select>
            <button type="button" id="puq-ws-php-save" class="btn btn-primary btn-sm"><i class="fa fa-save"></i> Apply</button>
            <button type="button" id="puq-ws-php-cancel" class="btn btn-default btn-sm" style="display:none;" title="Cancel queued change"><i class="fa fa-ban"></i></button>
            <span class="puq-ws-status" id="puq-ws-php-status"></span>
        </div>
        <p class="puq-ws-help">Backend template applied to the main domain. Available versions come from <code>v-list-sys-php</code> via the cached server status_data.</p>
    </div>

    <div class="puq-ws-section">
        <h4><i class="fa fa-lock" style="color:#5cb85c;"></i> HTTPS redirection</h4>
        <div class="puq-ws-row">
            <label style="margin:0;font-weight:normal;display:inline-flex;align-items:center;gap:6px;">
                <input type="checkbox" id="puq-ws-https-redirect"> Redirect HTTP &rarr; HTTPS
            </label>
            <button type="button" id="puq-ws-https-save" class="btn btn-primary btn-sm"><i class="fa fa-save"></i> Apply</button>
            <button type="button" id="puq-ws-https-cancel" class="btn btn-default btn-sm" style="display:none;" title="Cancel queued change"><i class="fa fa-ban"></i></button>
            <span class="puq-ws-status" id="puq-ws-https-status"></span>
        </div>
        <p class="puq-ws-help" id="puq-ws-https-help">Requires an active SSL certificate (Auto-SSL or Custom SSL).</p>
    </div>

    <div class="puq-ws-section">
        <h4>
            <i class="fa fa-bolt" style="color:#f0ad4e;"></i> Proxy extensions
            <span id="puq-ws-proxy-state" style="font-weight:normal;font-size:11px;margin-left:6px;"></span>
        </h4>
        <div class="puq-ws-row" style="align-items:flex-start;">
            <textarea id="puq-ws-proxy-ext" class="form-control" rows="3" spellcheck="false"
                style="flex:1 1 360px;min-width:280px;max-width:600px;font-family:monospace;font-size:12px;"
                placeholder="jpg, png, css, js, …"></textarea>
            <div style="display:flex;flex-direction:column;gap:6px;">
                <button type="button" id="puq-ws-proxy-save" class="btn btn-primary btn-sm"><i class="fa fa-save"></i> Apply</button>
                <button type="button" id="puq-ws-proxy-reset" class="btn btn-default btn-sm" title="Restore the recommended default list"><i class="fa fa-undo"></i> Defaults</button>
                <button type="button" id="puq-ws-proxy-disable" class="btn btn-warning btn-sm" title="Disable nginx static-file proxying entirely"><i class="fa fa-pause"></i> Disable proxy</button>
            </div>
            <span class="puq-ws-status" id="puq-ws-proxy-status"></span>
        </div>
        <p class="puq-ws-help">Listed extensions are served as static files by nginx (fast) instead of routed through PHP. Comma- or space-separated.</p>
    </div>
</div>

{literal}
<script>
(window.puqSvc = window.puqSvc || {}).init_web_settings = function(ctx){
    var esc = ctx.esc, baseUrl = ctx.baseUrl, puqId = ctx.puqId;

    var phpBusyLocal   = false;
    var httpsBusyLocal = false;
    var proxyBusyLocal = false;
    var proxyDefaultExt = '';
    var submittedProxyExt = null;
    var pollTimer = null;

    function spinnerBadge(){
        return '<i class="fa fa-spinner fa-spin" style="color:#337ab7;font-size:14px;"></i>';
    }
    function errorBadge(msg){
        return '<i class="fas fa-exclamation-triangle" style="color:#d9534f;cursor:help;font-size:14px;" title="' + esc(msg || 'Previous change failed') + '"></i>';
    }
    function renderTaskBadge($el, task){
        if (!task) { $el.empty(); return; }
        if (task.state === 'queued' || task.state === 'running') { $el.html(spinnerBadge()); return; }
        if (task.state === 'error') { $el.html(errorBadge()); return; }
        $el.empty();
    }
    function isTaskBusy(t){ return t && (t.state === 'queued' || t.state === 'running'); }

    function load(){
        $.ajax({
            url: baseUrl + 'getServiceWebSettings&id=' + puqId, dataType: 'json',
            success: function(r){
                var $state = $('#puq-ws-state');
                var $body  = $('#puq-ws-body');
                if (r.status !== 'success' || !r.data) {
                    $state.html('<div class="alert alert-danger">' + esc(r.msg || 'Failed to load') + '</div>');
                    return;
                }
                var d = r.data;
                var locked = (d.web_restore_lock || 0) === 1;
                $('#puq-ws-lock').toggle(locked);

                var phpServerBusy   = isTaskBusy(d.php_task);
                var httpsServerBusy = isTaskBusy(d.https_task);
                var proxyServerBusy = isTaskBusy(d.proxy_task) || isTaskBusy(d.proxy_off_task);

                if (!phpServerBusy   && phpBusyLocal)   phpBusyLocal   = false;
                if (!httpsServerBusy && httpsBusyLocal) httpsBusyLocal = false;
                if (!proxyServerBusy && proxyBusyLocal) proxyBusyLocal = false;

                var phpBusy   = phpServerBusy   || phpBusyLocal   || locked;
                var httpsBusy = httpsServerBusy || httpsBusyLocal || locked;
                var proxyBusy = proxyServerBusy || proxyBusyLocal || locked;

                // PHP dropdown
                var $sel = $('#puq-ws-php-select').empty();
                var tpls = d.templates || [];
                var curVersion = '';
                var cm = (d.current || '').match(/^PHP-(\d+)_(\d+)$/);
                if (cm) curVersion = cm[1] + '.' + cm[2];
                if (!tpls.length) {
                    $sel.append('<option value="">(no PHP versions detected on server)</option>').prop('disabled', true);
                    $('#puq-ws-php-save').prop('disabled', true);
                } else {
                    tpls.forEach(function(t){
                        var s = (t.version === curVersion) ? ' selected' : '';
                        $sel.append('<option value="' + esc(t.template) + '"' + s + '>PHP ' + esc(t.version) + '</option>');
                    });
                    $sel.prop('disabled', phpBusy);
                    $('#puq-ws-php-save').prop('disabled', phpBusy);
                }
                renderTaskBadge($('#puq-ws-php-status'), d.php_task);
                $('#puq-ws-php-cancel').toggle(phpServerBusy && d.php_task && d.php_task.state === 'queued');

                // HTTPS redirect
                var $cb = $('#puq-ws-https-redirect');
                $cb.prop('checked', !!d.https_redirect);
                if (!d.ssl_active) {
                    $cb.prop('disabled', true);
                    $('#puq-ws-https-save').prop('disabled', true);
                    $('#puq-ws-https-help').html('<i class="fa fa-info-circle"></i> Available when an SSL certificate is installed for this domain (issue Auto-SSL or upload Custom SSL first).');
                } else {
                    $cb.prop('disabled', httpsBusy);
                    $('#puq-ws-https-save').prop('disabled', httpsBusy);
                    $('#puq-ws-https-help').text('Requires an active SSL certificate (Auto-SSL or Custom SSL).');
                }
                renderTaskBadge($('#puq-ws-https-status'), d.https_task);
                $('#puq-ws-https-cancel').toggle(httpsServerBusy && d.https_task && d.https_task.state === 'queued');

                // Proxy
                var $pxArea = $('#puq-ws-proxy-ext');
                var px = d.proxy || {};
                if (px.default_ext) proxyDefaultExt = String(px.default_ext);
                var serverExt = String(px.extensions || '');
                if (submittedProxyExt !== null) {
                    if (proxyServerBusy) {
                        $pxArea.val(submittedProxyExt);
                    } else {
                        submittedProxyExt = null;
                        $pxArea.data('userEdited', false);
                        $pxArea.val(serverExt);
                    }
                } else if (!$pxArea.data('userEdited') || $pxArea.val() === '') {
                    $pxArea.val(serverExt);
                }
                var $pxState = $('#puq-ws-proxy-state');
                if (px.enabled) {
                    $pxState.html('<span style="color:#5cb85c;"><i class="fa fa-check-circle"></i> enabled</span>');
                } else {
                    $pxState.html('<span style="color:#999;"><i class="fa fa-pause-circle"></i> disabled</span>');
                }
                $pxArea.prop('disabled', proxyBusy);
                $('#puq-ws-proxy-save').prop('disabled', proxyBusy);
                $('#puq-ws-proxy-reset').prop('disabled', proxyBusy);
                $('#puq-ws-proxy-disable').prop('disabled', proxyBusy || !px.enabled);
                var proxyBadgeTask = d.proxy_task;
                if (d.proxy_off_task && (!proxyBadgeTask || (d.proxy_off_task.updated_at || '') > (proxyBadgeTask.updated_at || ''))) {
                    proxyBadgeTask = d.proxy_off_task;
                }
                renderTaskBadge($('#puq-ws-proxy-status'), proxyBadgeTask);

                $state.hide();
                $body.show();

                if (pollTimer) { clearTimeout(pollTimer); pollTimer = null; }
                if (phpBusy || httpsBusy || proxyBusy) pollTimer = setTimeout(load, 5000);
            },
            error: function(){
                $('#puq-ws-state').html('<div class="alert alert-danger">Request failed.</div>');
            }
        });
    }

    function lockPhp(){ phpBusyLocal = true; $('#puq-ws-php-select,#puq-ws-php-save').prop('disabled', true); $('#puq-ws-php-status').html(spinnerBadge()); }
    function restorePhp(){ phpBusyLocal = false; $('#puq-ws-php-select,#puq-ws-php-save').prop('disabled', false); $('#puq-ws-php-status').empty(); }
    function lockHttps(){ httpsBusyLocal = true; $('#puq-ws-https-redirect,#puq-ws-https-save').prop('disabled', true); $('#puq-ws-https-status').html(spinnerBadge()); }
    function restoreHttps(){ httpsBusyLocal = false; $('#puq-ws-https-redirect,#puq-ws-https-save').prop('disabled', false); $('#puq-ws-https-status').empty(); }
    function lockProxy(){ proxyBusyLocal = true; $('#puq-ws-proxy-ext,#puq-ws-proxy-save,#puq-ws-proxy-reset,#puq-ws-proxy-disable').prop('disabled', true); $('#puq-ws-proxy-status').html(spinnerBadge()); }
    function restoreProxy(){ proxyBusyLocal = false; $('#puq-ws-proxy-ext,#puq-ws-proxy-save,#puq-ws-proxy-reset,#puq-ws-proxy-disable').prop('disabled', false); $('#puq-ws-proxy-status').empty(); }

    $('#tab-web_settings #puq-ws-php-save').on('click', function(){
        if (phpBusyLocal) return;
        var tpl = $('#puq-ws-php-select').val();
        if (!tpl) return;
        lockPhp();
        $.ajax({ url: baseUrl + 'setServiceBackendTemplate', type: 'POST',
            data: { id: puqId, template: tpl }, dataType: 'json',
            success: function(r){
                if (r.status === 'success') { showNotification(r.msg || 'PHP change queued', 'success'); load(); }
                else { showNotification(r.msg || 'Failed', 'error'); restorePhp(); }
            },
            error: function(){ showNotification('Request failed', 'error'); restorePhp(); }
        });
    });

    $('#tab-web_settings #puq-ws-https-save').on('click', function(){
        if (httpsBusyLocal) return;
        var enabled = $('#puq-ws-https-redirect').is(':checked') ? 1 : 0;
        lockHttps();
        $.ajax({ url: baseUrl + 'setServiceHttpsRedirect', type: 'POST',
            data: { id: puqId, enabled: enabled }, dataType: 'json',
            success: function(r){
                if (r.status === 'success') { showNotification(r.msg || 'HTTPS redirect change queued', 'success'); load(); }
                else { showNotification(r.msg || 'Failed', 'error'); restoreHttps(); }
            },
            error: function(){ showNotification('Request failed', 'error'); restoreHttps(); }
        });
    });

    $('#tab-web_settings #puq-ws-proxy-ext').on('input', function(){ $(this).data('userEdited', true); });

    function validateProxy(raw){
        raw = String(raw || '').trim();
        if (raw === '') return { ok: false, msg: 'At least one extension is required. Use Defaults to restore.' };
        if (raw.length > 2048) return { ok: false, msg: 'Extension list is too long (max 2048 chars).' };
        var tokens = raw.split(/[\s,]+/).filter(Boolean);
        if (tokens.length === 0) return { ok: false, msg: 'At least one extension is required.' };
        if (tokens.length > 200) return { ok: false, msg: 'Too many extensions (max 200).' };
        var seen = {};
        for (var i = 0; i < tokens.length; i++) {
            var t = tokens[i];
            if (t.length > 20) return { ok: false, msg: 'Extension too long (max 20 chars): ' + t };
            if (!/^[A-Za-z0-9]+$/.test(t)) {
                return { ok: false, msg: 'Invalid extension: ' + t + ' — letters and digits only' };
            }
            seen[t.toLowerCase()] = true;
        }
        return { ok: true, normalised: Object.keys(seen).join(',') };
    }

    $('#tab-web_settings #puq-ws-proxy-save').on('click', function(){
        if (proxyBusyLocal) return;
        var raw = String($('#puq-ws-proxy-ext').val() || '');
        var v = validateProxy(raw);
        if (!v.ok) { showNotification(v.msg, 'error'); return; }
        lockProxy();
        submittedProxyExt = v.normalised;
        $('#puq-ws-proxy-ext').val(v.normalised);
        $.ajax({ url: baseUrl + 'setServiceProxyExtensions', type: 'POST',
            data: { id: puqId, extensions: v.normalised, template: 'default' }, dataType: 'json',
            success: function(r){
                if (r.status === 'success') { showNotification(r.msg || 'Proxy update queued', 'success'); load(); }
                else { submittedProxyExt = null; $('#puq-ws-proxy-ext').data('userEdited', false); showNotification(r.msg || 'Failed', 'error'); restoreProxy(); }
            },
            error: function(){ submittedProxyExt = null; showNotification('Request failed', 'error'); restoreProxy(); }
        });
    });

    $('#tab-web_settings #puq-ws-proxy-reset').on('click', function(){
        if (proxyDefaultExt === '') { showNotification('Default list not loaded yet', 'error'); return; }
        $('#puq-ws-proxy-ext').val(proxyDefaultExt).data('userEdited', true);
    });

    $('#tab-web_settings #puq-ws-proxy-disable').on('click', function(){
        if (proxyBusyLocal) return;
        puqConfirm({
            type: 'warning', icon: 'fa-pause',
            title: 'Disable nginx static-file proxy?',
            text: 'All requests (including static assets) will be routed through PHP-FPM. You can re-enable any time by applying an extension list.',
            ok: 'Disable proxy', cancel: 'Cancel',
            onConfirm: function(){
                return new Promise(function(resolve, reject){
                    lockProxy();
                    $.ajax({ url: baseUrl + 'disableServiceProxy', type: 'POST',
                        data: { id: puqId }, dataType: 'json',
                        success: function(r){
                            if (r.status === 'success') { showNotification(r.msg || 'Proxy disable queued', 'success'); load(); resolve(); }
                            else { restoreProxy(); reject(new Error(r.msg || 'Failed')); }
                        },
                        error: function(){ restoreProxy(); reject(new Error('Request failed')); }
                    });
                });
            }
        });
    });

    function bindCancel(btnId, kind){
        $('#tab-web_settings ' + btnId).on('click', function(){
            $.ajax({ url: baseUrl + 'cancelServiceWebTask', type: 'POST',
                data: { id: puqId, kind: kind }, dataType: 'json',
                success: function(r){
                    if (r.status === 'success') { showNotification(r.msg || 'Cancelled', 'success'); load(); }
                    else showNotification(r.msg || 'Failed', 'error');
                }
            });
        });
    }
    bindCancel('#puq-ws-php-cancel', 'php_version');
    bindCancel('#puq-ws-https-cancel', 'https_redirect');

    load();
};
</script>
{/literal}
