{* Deploy tab — persistent deploy log + status + hard-reset Redeploy. The
   log is drawn from puqWebHosting_services.deploy_log (JSON, append-only).
   Redeploy here is the same hard-reset path as the header button: only
   allowed when deploy_status='error'. *}
<style>
.puq-deploy-status-bar { display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:12px; }
.puq-deploy-status-bar .label { font-size:14px; padding:6px 10px; }
.puq-deploy-status-bar .puq-progress { flex:1; min-width:200px; }
.puq-deploy-status-bar .progress { margin-bottom:0; height:18px; }
.puq-deploy-error { white-space:pre-wrap; word-break:break-word; }
.puq-deploy-counts { display:flex; gap:14px; margin-bottom:10px; font-size:12px; color:#555; flex-wrap:wrap; }
.puq-deploy-counts span code { padding:1px 5px; background:#f5f5f5; border-radius:2px; }
.puq-deploy-timeline { border-left:3px solid #ddd; padding-left:14px; margin-left:6px; max-height:520px; overflow-y:auto; background:#fff; padding:10px 12px 10px 18px; border-radius:3px; }
.puq-deploy-entry { position:relative; padding:6px 0 6px 0; border-bottom:1px dashed #eee; }
.puq-deploy-entry:last-child { border-bottom:none; }
.puq-deploy-entry .puq-dot { position:absolute; left:-22px; top:10px; width:10px; height:10px; border-radius:50%; background:#ccc; }
.puq-deploy-entry.success .puq-dot { background:#5cb85c; }
.puq-deploy-entry.error   .puq-dot { background:#d9534f; }
.puq-deploy-entry.started .puq-dot { background:#5bc0de; }
.puq-deploy-entry.info    .puq-dot { background:#999; }
.puq-deploy-entry.redeploy .puq-dot { background:#f0ad4e; }
.puq-deploy-entry .puq-time { font-size:11px; color:#888; }
.puq-deploy-entry .puq-action { font-family:monospace; font-size:12px; color:#337ab7; }
.puq-deploy-entry .puq-msg { font-size:12px; color:#333; margin-top:2px; word-break:break-word; }
.puq-deploy-entry.error .puq-msg { color:#a94442; }
</style>

<div class="puq-deploy-status-bar">
    <strong>Deploy status:</strong>
    <span id="puq-deploy-status-badge" class="label label-default">…</span>
    <span class="puq-progress">
        <div class="progress">
            <div id="puq-deploy-progress-bar" class="progress-bar progress-bar-info" role="progressbar" style="width:0%;">0%</div>
        </div>
    </span>
    <button type="button" class="btn btn-default btn-sm" id="puq-deploy-refresh"><i class="fa fa-sync"></i> Refresh</button>
    <button type="button" class="btn btn-warning btn-sm" id="puq-deploy-redeploy" disabled
            title="Hard reset: deletes Hestia user(s) and re-creates everything. Only enabled when deploy_status=error.">
        <i class="fa fa-redo-alt"></i> Redeploy (hard reset)
    </button>
</div>

<div class="puq-deploy-counts" id="puq-deploy-counts"></div>

<div id="puq-deploy-error-wrap" style="display:none;" class="alert alert-danger">
    <strong><i class="fa fa-exclamation-triangle"></i> Deploy error:</strong>
    <div class="puq-deploy-error" id="puq-deploy-error-text"></div>
</div>

<h5 style="margin-top:14px;"><i class="fa fa-stream"></i> Timeline <small class="text-muted">(newest first, last 200 events)</small></h5>
<div class="puq-deploy-timeline" id="puq-deploy-timeline">
    <div class="text-muted text-center"><i class="fa fa-spinner fa-spin"></i> Loading…</div>
</div>

{literal}
<script>
(window.puqSvc = window.puqSvc || {}).init_deploy = function(ctx){
    var esc = ctx.esc, baseUrl = ctx.baseUrl, whmcsId = ctx.whmcsId, fmtDate = ctx.fmtDate;
    var armAutoRefresh = ctx.armAutoRefresh;

    var statusClass = window.statusClass;
    function eventClass(ev) {
        return ({success:'success', error:'error', started:'started',
                 info:'info', redeploy:'redeploy', rollback:'redeploy'})[ev] || 'info';
    }
    function eventIcon(ev) {
        return ({success:'fa-check', error:'fa-times', started:'fa-play',
                 info:'fa-info-circle', redeploy:'fa-redo', rollback:'fa-undo'})[ev] || 'fa-circle';
    }

    function load() {
        puqAjax({
            container: '#puq-deploy-timeline',
            loadingCaption: 'Loading deploy log…',
            url: baseUrl + 'deployState&service_id=' + whmcsId,
            success: function(r) {
                if (r.status !== 'success' || !r.data) {
                    $('#puq-deploy-timeline').html('<div class="alert alert-danger">' + esc(r.msg || 'Failed to load') + '</div>');
                    return;
                }
                var d = r.data;

                $('#puq-deploy-status-badge')
                    .removeClass()
                    .addClass('label label-' + statusClass(d.deploy_status))
                    .text(d.deploy_status || '—');

                $('#puq-deploy-progress-bar')
                    .css('width', (d.percent || 0) + '%')
                    .text((d.percent || 0) + '%');

                var $btn = $('#puq-deploy-redeploy');
                if (d.can_redeploy) {
                    $btn.prop('disabled', false).removeClass('btn-default').addClass('btn-warning');
                } else {
                    $btn.prop('disabled', true).removeClass('btn-warning').addClass('btn-default');
                }

                var counts = d.counts || {};
                var parts = [];
                ['queued','running','success','error','cancelled'].forEach(function(k){
                    if (counts[k] != null && counts[k] > 0) {
                        parts.push('<span>' + esc(k) + ': <code>' + esc(counts[k]) + '</code></span>');
                    }
                });
                $('#puq-deploy-counts').html(parts.length ? parts.join('') : '<span class="text-muted">No tasks yet.</span>');

                if (d.deploy_error) {
                    $('#puq-deploy-error-text').text(d.deploy_error);
                    $('#puq-deploy-error-wrap').show();
                } else {
                    $('#puq-deploy-error-wrap').hide();
                }

                var $tl = $('#puq-deploy-timeline').empty();
                var log = d.log || [];
                if (!log.length) {
                    $tl.html('<div class="text-muted text-center">No deploy events yet.</div>');
                    return;
                }
                log.forEach(function(e) {
                    var cls = eventClass(e.event);
                    var icon = eventIcon(e.event);
                    var dur = e.duration != null ? ' <small class="text-muted">' + esc(e.duration) + 's</small>' : '';
                    var att = e.attempt ? ' <small class="text-muted">[attempt ' + esc(e.attempt) + ']</small>' : '';
                    var task = e.task_id ? ' <small class="text-muted">task#' + esc(e.task_id) + '</small>' : '';
                    var msg = e.message ? '<div class="puq-msg">' + esc(e.message) + '</div>' : '';
                    $tl.append(
                        '<div class="puq-deploy-entry ' + cls + '">' +
                          '<span class="puq-dot"></span>' +
                          '<span class="puq-time">' + fmtDate(e.time) + '</span> ' +
                          '<i class="fa ' + icon + ' text-muted"></i> ' +
                          '<span class="puq-action">' + esc(e.action || e.event) + '</span>' +
                          att + dur + task +
                          msg +
                        '</div>'
                    );
                });
            }
        });
    }

    // Auto-refresh while in transient states (queued / deploying / rolling_back).
    load = armAutoRefresh('deploy', {
        selector: '#puq-deploy-status-badge',
        states: ['queued','deploying','rolling_back'],
        load: load,
    });

    // Expose for outer-page invalidation (header Redeploy button).
    window.puqSvc.refresh_deploy = load;

    $('#puq-deploy-refresh').on('click', function(){ load(); });

    $('#puq-deploy-redeploy').on('click', function(){
        if ($(this).prop('disabled')) return;
        puqConfirm({
            type: 'danger', icon: 'fa-redo-alt',
            title: 'Hard-reset redeploy?',
            text: 'Deletes the panel user(s) for this service, wipes local mailboxes / databases / FTP / DNS rows, then re-runs the full provisioning chain. <strong>Only works when the service is in error state.</strong>',
            ok: 'Redeploy', cancel: 'Cancel',
            onConfirm: function(){
                return new Promise(function(resolve, reject){
                    $.ajax({
                        url: baseUrl + 'redeployService', type: 'POST',
                        data: { service_id: whmcsId }, dataType: 'json',
                        success: function(r){
                            if (r.status === 'success') { showNotification(r.msg || 'Redeploy queued.', 'success'); setTimeout(load, 500); resolve(); }
                            else reject(new Error(r.msg || 'Failed'));
                        },
                        error: function(){ reject(new Error('Request failed')); }
                    });
                });
            }
        });
    });

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