/**
 * UltraGuard Pro — File Integrity Checker real-time monitor
 *
 * DOM contract — what the PHP RenderEngine actually outputs:
 *
 *   #fc-scan-progress-card
 *     .ultraguard-card-title
 *       .ultraguard-badge              ← status badge (no fc-scan-badge class)
 *     #fc-scan-progress-bar            ← render_wrapper outer div
 *       .ultraguard-security-suitegress-bar       ← actual CSS fill bar (set width here)
 *       [data-rt-progress-label]       ← percentage text span
 *   .fc-live-stats-row                 ← renderer list wrapper
 *     .ultraguard-list-item            ← Files / Changes / Elapsed rows
 *       .ultraguard-list-badge         ← live value badge
 *   .fc-current-file                   ← current file div
 *
 * Badge classes the PHP card renderer outputs:
 *   ultraguard-badge ultraguard-badge-{type}
 *   (badge['class'] key in scheme is ignored by the renderer)
 *
 * @package UltraGuardPro\modules\filechecker
 */
(function ($) {
    'use strict';

    if (typeof $ === 'undefined') {
        console.error('[UG FC] jQuery not available');
        return;
    }

    /* ── Config ──────────────────────────────────────────────────────────────── */
    var CFG = {
        pollInterval  : 2000,
        maxErrors     : 6,
        completeDelay : 2500,
        ajaxurl       : (window.ultraguardAdmin || window.ultraguardPro || {}).ajaxurl
                        || window.ajaxurl
                        || '/wp-admin/admin-ajax.php',
        nonce         : (window.ultraguardFcData || {}).nonce || ''
    };

    /* ── State ───────────────────────────────────────────────────────────────── */
    var state = {
        polling      : false,
        pollTimer    : null,
        scanId       : null,
        scanType     : '',
        errors       : 0,
        startedAt    : 0,
        lastPercent  : 0,
        elapsedTimer : null
    };

    /* ── AJAX helper ─────────────────────────────────────────────────────────── */
    function post(action, data) {
        return $.ajax({
            url      : CFG.ajaxurl,
            type     : 'POST',
            dataType : 'json',
            data     : $.extend({ action: action, nonce: CFG.nonce }, data || {})
        });
    }

    /* ── Corrected DOM selectors ─────────────────────────────────────────────── */
    function card()         { return $('#fc-scan-progress-card'); }

    // Status badge rendered in card header — .ultraguard-badge (fc-scan-badge class ignored by renderer)
    function badge()        { return card().find('.ultraguard-card-title .ultraguard-badge'); }

    // Outer progress wrapper (render_wrapper with id="fc-scan-progress-bar")
    function progressWrap() { return $('#fc-scan-progress-bar'); }

    // Actual CSS fill bar nested inside
    function progressBar()  { return $('#fc-scan-progress-bar .ultraguard-security-suitegress-bar'); }

    // Percentage text — PHP outputs [data-rt-progress-label], not .fc-progress-pct
    function progressPct()  { return $('#fc-scan-progress-bar [data-rt-progress-label]'); }
    function liveStats()    { return card().find('.fc-live-stats-row'); }

    /* ── Initialise ──────────────────────────────────────────────────────────── */
    function init() {
        if (!$('.ultraguard-filechecker-dashboard-page, [id*="filechecker"]').length &&
            !card().length) {
            registerRealtimeRenderer();
            return;
        }

        registerRealtimeRenderer();
        bindEvents();
        checkForActiveScan();
    }

    /* ── Event bindings ──────────────────────────────────────────────────────── */
    function bindEvents() {
        $(document).on('ultraguard:ajax:success', function (e, response, requestData) {
            var action = (requestData && requestData.action) || '';

            // Scan started
            if (action === 'ultraguard_fc_start_full_scan' ||
                action === 'ultraguard_fc_start_quick_scan') {

                var d = (response && response.data) ? response.data : {};
                state.scanId    = d.scan_id   || null;
                state.scanType  = (action === 'ultraguard_fc_start_full_scan') ? 'Full' : 'Quick';
                state.startedAt = Date.now();

                setRunningUI(true, state.scanType);
                startPolling();

                if (window.UltraGuardRealtime) {
                    window.UltraGuardRealtime.subscribe('filechecker_progress');
                    window.UltraGuardRealtime.forceRefresh('filechecker_progress');
                }
            }

            // Scan cancelled via AJAX
            if (action === 'ultraguard_fc_cancel_scan') {
                handleScanFinished({ status: 'cancelled' });
            }
        });
    }

    /* ── On-load active scan check ───────────────────────────────────────────── */
    function checkForActiveScan() {
        post('ultraguard_fc_get_scan_progress')
            .done(function (resp) {
                if (!resp || !resp.success) { return; }
                var d = resp.data || {};
                if (d.is_scanning) {
                    state.scanId    = d.session_id || null;
                    state.scanType  = d.type ? capitalise(d.type) : 'Full';
                    state.startedAt = d.started_at
                        ? (parseInt(d.started_at, 10) * 1000) : Date.now();
                    setRunningUI(true, state.scanType);
                    updateProgressUI(d);
                    startPolling();
                }
            });
    }

    /* ── Polling loop ────────────────────────────────────────────────────────── */
    function startPolling() {
        if (state.polling) { return; }
        state.polling = true;
        state.errors  = 0;
        startElapsedTimer();
        poll();
    }

    function stopPolling() {
        state.polling = false;
        if (state.pollTimer)    { clearTimeout(state.pollTimer);    state.pollTimer    = null; }
        if (state.elapsedTimer) { clearInterval(state.elapsedTimer); state.elapsedTimer = null; }
    }

    function poll() {
        if (!state.polling) { return; }

        post('ultraguard_fc_get_scan_progress')
            .done(function (resp) {
                state.errors = 0;
                if (!resp || !resp.success) { scheduleNextPoll(); return; }
                var d = resp.data || {};
                if (!d.is_scanning) {
                    handleScanFinished({ status: 'completed' });
                    return;
                }
                updateProgressUI(d);
                scheduleNextPoll();
            })
            .fail(function () {
                state.errors++;
                if (state.errors >= CFG.maxErrors) {
                    stopPolling();
                    toast('error', ugFcI18n('lostConnection'));
                } else {
                    scheduleNextPoll();
                }
            });
    }

    function scheduleNextPoll() {
        if (!state.polling) { return; }
        state.pollTimer = setTimeout(poll, CFG.pollInterval);
    }

    /* ── Elapsed timer ───────────────────────────────────────────────────────── */
    function startElapsedTimer() {
        if (state.elapsedTimer) { return; }
        state.elapsedTimer = setInterval(function () {
            if (!state.startedAt) { return; }
            var secs = Math.floor((Date.now() - state.startedAt) / 1000);
            var $stats = liveStats().find('.ultraguard-list-item');
            if ($stats.length >= 3) {
                $stats.eq(2).find('.ultraguard-list-badge').text(formatDuration(secs));
            }
        }, 1000);
    }

    /* ── Running / idle UI ───────────────────────────────────────────────────── */
    function setRunningUI(running, scanType) {
        if (running) {
            // Animate the fill bar
            progressBar().addClass('fc-animated fc-striped');

            // Update badge — PHP uses ultraguard-badge-{type}, not badge-{type}
            setBadgeState('warning', (scanType || 'Full') + ' — ' + ugFcI18n('running'));

            // Show live stats row
            card().find('.fc-live-stats-row').removeClass('fc-hidden').show();
            card().find('.fc-current-file').show();

            // Disable start buttons, enable cancel via its AJAX data-attribute
            $('[data-ajax-action="ultraguard_fc_start_full_scan"],' +
              '[data-ajax-action="ultraguard_fc_start_quick_scan"]')
                .prop('disabled', true).addClass('fc-disabled');

        } else {
            progressBar().removeClass('fc-animated fc-striped');

            setBadgeState('secondary', ugFcI18n('idle'));

            $('[data-ajax-action="ultraguard_fc_start_full_scan"],' +
              '[data-ajax-action="ultraguard_fc_start_quick_scan"]')
                .prop('disabled', false).removeClass('fc-disabled');
        }
    }

    /**
     * Swap the card-header badge to reflect current state.
     * PHP: <span class="ultraguard-badge ultraguard-badge-{type}">text</span>
     */
    function setBadgeState(type, text) {
        var $b = badge();
        if (!$b.length) { return; }

        // Remove all existing ultraguard-badge-* classes
        $b.removeClass(function (i, cls) {
            return (cls.match(/\bultraguard-badge-\S+/g) || []).join(' ');
        });
        $b.addClass('ultraguard-badge-' + type);

        if (text !== undefined) { $b.text(text); }
    }

    /* ── Progress UI update ──────────────────────────────────────────────────── */
    function updateProgressUI(d) {
        var pct     = parseInt(d.percent || d.progress || 0, 10);
        var curFile = d.current_file    || '';
        var changes = parseInt(d.changes_found   || 0, 10);
        var files   = parseInt(d.files_processed || 0, 10);
        var type    = d.type ? capitalise(d.type) : (state.scanType || 'Full');

        pct = Math.min(100, Math.max(0, pct));

        // Never go backwards unless at 100 %
        if (pct < state.lastPercent && state.lastPercent < 100) {
            pct = state.lastPercent;
        }
        state.lastPercent = pct;

        // Update actual CSS fill bar (class .ultraguard-security-suitegress-bar)
        progressBar().css('width', pct + '%').attr('aria-valuenow', pct);

        // Update percentage text ([data-rt-progress-label])
        progressPct().text(pct + '%');

        // Live counters rendered as list rows by PHP
        var $stats = liveStats().find('.ultraguard-list-item');
        if ($stats.length >= 1) {
            $stats.eq(0).find('.ultraguard-list-badge').text(files.toLocaleString());
        }
        if ($stats.length >= 2) {
            $stats.eq(1).find('.ultraguard-list-badge').text(changes.toLocaleString());
        }

        // Current file path
        if (curFile) {
            var display = curFile.length > 65 ? '…' + curFile.slice(-62) : curFile;
            $('.fc-current-file').text(display).attr('title', curFile).show();
        }

        // Update badge text with live %
        badge().text(type + ' — ' + ugFcI18n('scanning') + ' ' + pct + '%');

        // Store started_at for elapsed timer
        if (d.started_at && !state.startedAt) {
            state.startedAt = parseInt(d.started_at, 10) * 1000;
        }
    }

    /* ── Scan finished ───────────────────────────────────────────────────────── */
    function handleScanFinished(data) {
        var status = (data && data.status) || 'completed';
        stopPolling();
        state.lastPercent = 0;
        state.scanId      = null;

        if (status === 'completed') {
            progressBar().css('width', '100%').removeClass('fc-animated fc-striped');
            progressPct().text('100%');
            setBadgeState('success', ugFcI18n('complete'));
            toast('success', ugFcI18n('scanComplete'));
        } else if (status === 'cancelled') {
            progressBar().removeClass('fc-animated fc-striped');
            setBadgeState('secondary', ugFcI18n('cancelled'));
            toast('info', ugFcI18n('scanCancelled'));
        } else {
            progressBar().removeClass('fc-animated fc-striped');
            setBadgeState('danger', ugFcI18n('error'));
        }

        setRunningUI(false);

        if (window.UltraGuardRealtime) {
            window.UltraGuardRealtime.forceRefresh('filechecker_progress');
        }

        setTimeout(function () { window.location.reload(); }, CFG.completeDelay);
    }

    /* ── Realtime renderer ───────────────────────────────────────────────────── */
    function registerRealtimeRenderer() {
        if (!window.UltraGuardRealtime) { return; }

        window.UltraGuardRealtime.addRenderer('filechecker_progress', function (d) {
            if (d.is_scanning) {
                if (!state.polling) {
                    state.scanId    = d.session_id || null;
                    state.scanType  = d.type ? capitalise(d.type) : 'Full';
                    state.startedAt = d.started_at
                        ? (parseInt(d.started_at, 10) * 1000) : Date.now();
                    setRunningUI(true, state.scanType);
                    startPolling();
                }
                updateProgressUI(d);
            } else if (state.polling) {
                handleScanFinished({ status: 'completed' });
            }
        });
    }

    /* ── Toast ───────────────────────────────────────────────────────────────── */
    // UltraGuardManagers.showToast does not exist — correct call is UltraGuardComponents.showMessage
    function toast(type, message) {
        if (window.UltraGuardComponents && window.UltraGuardComponents.showMessage) {
            window.UltraGuardComponents.showMessage(
                { escapeHtml: function (s) { return $('<div>').text(s).html(); } },
                message,
                type,
                5000
            );
        } else if (window.console) {
        }
    }

    /* ── Helpers ─────────────────────────────────────────────────────────────── */
    function capitalise(s) {
        return s ? (s.charAt(0).toUpperCase() + s.slice(1)) : '';
    }

    function formatDuration(totalSecs) {
        var h = Math.floor(totalSecs / 3600);
        var m = Math.floor((totalSecs % 3600) / 60);
        var s = totalSecs % 60;
        if (h > 0) { return h + 'h ' + pad(m) + 'm ' + pad(s) + 's'; }
        if (m > 0) { return m + 'm ' + pad(s) + 's'; }
        return s + 's';
    }

    function pad(n) { return n < 10 ? '0' + n : '' + n; }

    /* ── i18n ────────────────────────────────────────────────────────────────── */
    var _i18n = $.extend({
        running        : 'Running\u2026',
        scanning       : 'Scanning\u2026',
        idle           : 'Idle',
        complete       : 'Complete',
        cancelled      : 'Cancelled',
        error          : 'Error',
        scanComplete   : 'Scan complete \u2014 results updated.',
        scanCancelled  : 'Scan cancelled.',
        lostConnection : 'Lost connection to scan. Please refresh the page.'
    }, (window.ultraguardFcData || {}).i18n || {});

    function ugFcI18n(key) { return _i18n[key] || key; }

    /* ── Inject supporting CSS ───────────────────────────────────────────────── */
    function injectStyles() {
        if ($('#ug-fc-live-styles').length) { return; }
        var css =
            /* Animated striped fill bar */
            '.fc-animated{transition:width .4s ease!important}' +
            '.fc-striped.ultraguard-security-suitegress-bar{' +
                'background-image:linear-gradient(45deg,rgba(255,255,255,.18) 25%,transparent 25%,' +
                'transparent 50%,rgba(255,255,255,.18) 50%,rgba(255,255,255,.18) 75%,transparent 75%)!important;' +
                'background-size:28px 28px!important;' +
                'animation:ug-fc-stripe .7s linear infinite!important}' +
            '@keyframes ug-fc-stripe{0%{background-position:0 0}100%{background-position:28px 0}}' +
            /* Utility */
            '.fc-hidden{display:none!important}' +
            '.fc-disabled{opacity:.55;pointer-events:none}' +
            /* Current file ticker */
            '.fc-current-file{font-size:11px;color:var(--ug-gray,#64748b);' +
                'font-family:var(--ug-font-mono,"SF Mono",Monaco,Consolas,monospace);' +
                'white-space:nowrap;overflow:hidden;text-overflow:ellipsis;' +
                'max-width:100%;display:block;margin-top:6px}' +
            /* Live stats row */
            '.fc-live-stats-row{margin-top:8px;font-size:12px;color:var(--ug-gray,#64748b);' +
                'display:flex;flex-wrap:wrap;gap:14px}' +
            '.fc-live-stats-row span{white-space:nowrap}' +
            '.fc-elapsed-time{font-variant-numeric:tabular-nums}';

        $('<style id="ug-fc-live-styles">').text(css).appendTo('head');
    }

    /* ── Boot ────────────────────────────────────────────────────────────────── */
    $(function () {
        injectStyles();
        init();

        if ($('.ultraguard-filechecker-dashboard-page, [id*="filechecker"]').length ||
            card().length) {
            if (window.UltraGuardRealtime) {
                window.UltraGuardRealtime.subscribe('filechecker_progress');
            }
        }
    });

}(window.jQuery || {}));
