// Shared build-progress overlay — window.PPBuildProgress.
//
// The SAME full-screen, step-based "Building your app" screen the Finished module
// shows, so a build started from ANY SPA page (Designer, Tables, Fields, Events,
// Workspace…) looks and behaves identically. Kept in lockstep with the buildLock
// in modules/Finished/Views/scripts/core.js.
//
// API:  PPBuildProgress.show()            — open the overlay, begin the animation
//       PPBuildProgress.done(ok, message) — resolve to success/failure
//       PPBuildProgress.hide()            — close immediately
//
// There is no server-sent progress stream (a build is one request), so the steps
// advance on a gentle timer and HOLD at "verifying" until done() lands.
(function () {
    if (window.PPBuildProgress) return;   // already loaded

    const STEPS = [
        { k: 'collect',  t: 'Collecting your design' },
        { k: 'send',     t: 'Sending it to the build server' },
        { k: 'assemble', t: 'Assembling your app on the server' },
        { k: 'generate', t: 'Generating pages, forms & logic' },
        { k: 'verify',   t: 'Verifying every file' },
        { k: 'place',    t: 'Placing the finished app in your project' },
    ];
    const MSGS = [
        'Reading your pages, tables and events…',
        'Turning your design into real code…',
        'Wiring up forms, lists and dashboards…',
        'Applying your theme and settings…',
        'Almost there — putting it all together…',
    ];
    let el = null, stepTimer = null, msgTimer = null, cur = 0;
    const beforeUnload = (e) => { e.preventDefault(); e.returnValue = 'A build is in progress. Leaving now will cancel it.'; return e.returnValue; };

    function ensure() {
        if (el) return el;
        el = document.createElement('div');
        el.className = 'fx-buildlock';
        el.setAttribute('role', 'alertdialog');
        el.setAttribute('aria-live', 'assertive');
        el.innerHTML =
            '<div class="fx-bl-card">' +
              '<div class="fx-bl-orb"><i class="bi bi-hammer"></i></div>' +
              '<h2 class="fx-bl-title">Building your app</h2>' +
              '<p class="fx-bl-msg" id="fxBlMsg">Starting…</p>' +
              '<ul class="fx-bl-steps" id="fxBlSteps">' +
                STEPS.map((s) => `<li class="fx-bl-step" data-k="${s.k}"><span class="dot"></span><span>${s.t}</span></li>`).join('') +
              '</ul>' +
              '<div class="fx-bl-bar" id="fxBlBar"></div>' +
              '<p class="fx-bl-foot"><i class="bi bi-shield-lock me-1"></i>Please keep this tab open — your existing app stays live until the new one is ready.</p>' +
              '<button type="button" class="btn btn-outline-secondary btn-sm fx-bl-close" id="fxBlClose">Close</button>' +
            '</div>';
        document.body.appendChild(el);
        el.querySelector('#fxBlClose').addEventListener('click', () => hide());
        el.addEventListener('keydown', (e) => { if (e.key === 'Escape') e.stopPropagation(); }, true);
        return el;
    }
    function paint(i) {
        cur = i;
        el.querySelectorAll('.fx-bl-step').forEach((li, n) => {
            li.classList.toggle('done', n < i);
            li.classList.toggle('active', n === i);
        });
    }
    function setMsg(txt) {
        const m = el.querySelector('#fxBlMsg');
        m.classList.add('swap');
        setTimeout(() => { m.textContent = txt; m.classList.remove('swap'); }, 160);
    }
    function show() {
        ensure();
        el.classList.remove('finished');
        el.querySelector('#fxBlBar').className = 'fx-bl-bar';
        el.querySelector('.fx-bl-title').textContent = 'Building your app';
        el.querySelector('.fx-bl-orb').innerHTML = '<i class="bi bi-hammer"></i>';
        el.querySelectorAll('.fx-bl-step').forEach((li) => li.classList.remove('fail', 'done', 'active'));
        el.classList.add('on');
        document.body.style.overflow = 'hidden';
        window.addEventListener('beforeunload', beforeUnload);
        paint(0);
        setMsg(MSGS[0]);
        const seq = [700, 900, 1400, 2600, 3200];
        let i = 0;
        const tick = () => {
            i++;
            if (i >= STEPS.length - 1) { paint(STEPS.length - 2); return; }   // hold at 'verify'
            paint(i);
            stepTimer = setTimeout(tick, seq[Math.min(i, seq.length - 1)]);
        };
        stepTimer = setTimeout(tick, seq[0]);
        let mi = 0;
        msgTimer = setInterval(() => { mi = (mi + 1) % MSGS.length; setMsg(MSGS[mi]); }, 2600);
    }
    function stopTimers() { clearTimeout(stepTimer); clearInterval(msgTimer); stepTimer = msgTimer = null; }
    function done(ok, msg) {
        if (!el) return;
        stopTimers();
        window.removeEventListener('beforeunload', beforeUnload);
        if (ok) {
            el.querySelectorAll('.fx-bl-step').forEach((li) => { li.classList.remove('active'); li.classList.add('done'); });
            el.querySelector('#fxBlBar').className = 'fx-bl-bar done';
            el.querySelector('.fx-bl-title').textContent = 'Build complete';
            el.querySelector('.fx-bl-orb').innerHTML = '<i class="bi bi-check-circle-fill" style="color:#16a34a"></i>';
            setMsg(msg || 'Your app is ready.');
            setTimeout(() => hide(), 950);
        } else {
            const steps = el.querySelectorAll('.fx-bl-step');
            (steps[cur] || steps[steps.length - 1]).classList.add('fail');
            el.querySelector('#fxBlBar').className = 'fx-bl-bar fail';
            el.querySelector('.fx-bl-title').textContent = 'Build stopped';
            el.querySelector('.fx-bl-orb').innerHTML = '<i class="bi bi-exclamation-octagon-fill" style="color:#dc2626"></i>';
            setMsg(msg || 'The build could not be completed.');
            el.classList.add('finished');
        }
    }
    function hide() {
        if (!el) return;
        stopTimers();
        window.removeEventListener('beforeunload', beforeUnload);
        el.classList.remove('on', 'finished');
        document.body.style.overflow = '';
    }
    window.PPBuildProgress = { show, done, hide };
})();
