/**
 * Autoguardado del asistente de instalación (servidor + localStorage/sessionStorage).
 */
(function (global) {
    'use strict';

    var LS_KEY = 'flexia_install_wizard_v1';
    var PWD_KEY = 'flexia_install_wizard_pwd_v1';
    var DEBOUNCE_MS = 650;
    var PERIOD_MS = 20000;

    var timer = null;
    var saving = false;
    var meta = null;

    function cfg() {
        return meta || global.INSTALL_WIZARD_PERSIST || null;
    }

    function clearLocalWizardStorage() {
        [1, 2, 3].forEach(function (step) {
            try {
                localStorage.removeItem(storageKey(step));
            } catch (e) {}
        });
        try {
            sessionStorage.removeItem(PWD_KEY);
        } catch (e) {}
    }

    function syncCsrfToken(token) {
        if (!token) {
            return;
        }
        var c = cfg();
        if (c) {
            c.csrf = token;
        }
        if (meta) {
            meta.csrf = token;
        }
        document.querySelectorAll('input[name="csrf"]').forEach(function (el) {
            el.value = token;
        });
    }

    function storageKey(step) {
        return LS_KEY + '_s' + String(step);
    }

    function readJson(key) {
        try {
            var raw = localStorage.getItem(key);
            if (!raw) return null;
            return JSON.parse(raw);
        } catch (e) {
            return null;
        }
    }

    function writeJson(key, obj) {
        try {
            localStorage.setItem(key, JSON.stringify(obj));
        } catch (e) {}
    }

    function readPwd() {
        try {
            return sessionStorage.getItem(PWD_KEY) || '';
        } catch (e) {
            return '';
        }
    }

    function writePwd(v) {
        try {
            if (v) sessionStorage.setItem(PWD_KEY, v);
            else sessionStorage.removeItem(PWD_KEY);
        } catch (e) {}
    }

    function syncGeoHidden(form) {
        if (!form) return;
        form.querySelectorAll('[data-install-location-block]').forEach(function (block) {
            if (typeof block._installGeoSync === 'function') {
                block._installGeoSync();
            }
        });
    }

    function syncPhones(form) {
        if (global.InstallPhone && typeof global.InstallPhone.syncAll === 'function') {
            global.InstallPhone.syncAll();
        }
    }

    function formToObject(form) {
        syncGeoHidden(form);
        syncPhones(form);
        var fd = new FormData(form);
        var out = {};
        fd.forEach(function (value, key) {
            if (value instanceof File) {
                return;
            }
            if (key === 'password' || key === 'password_confirm') {
                return;
            }
            if (Object.prototype.hasOwnProperty.call(out, key)) {
                if (!Array.isArray(out[key])) {
                    out[key] = [out[key]];
                }
                out[key].push(value);
            } else {
                out[key] = value;
            }
        });
        return out;
    }

    function setFieldValue(form, name, value) {
        var els = form.querySelectorAll('[name="' + name.replace(/"/g, '\\"') + '"]');
        if (!els.length) {
            var bracket = name.indexOf('[');
            if (bracket > 0) {
                els = form.querySelectorAll('[name="' + name.replace(/"/g, '\\"') + '"]');
            }
        }
        if (!els.length) {
            return;
        }
        var tag = els[0].tagName;
        var type = (els[0].type || '').toLowerCase();
        if (type === 'radio') {
            els.forEach(function (el) {
                el.checked = String(el.value) === String(value);
            });
            return;
        }
        if (type === 'checkbox') {
            if (els.length === 1) {
                els[0].checked = value === '1' || value === true || value === 'on';
            }
            return;
        }
        if (Array.isArray(value)) {
            els.forEach(function (el, idx) {
                if (idx < value.length) {
                    el.value = value[idx] == null ? '' : String(value[idx]);
                }
            });
            return;
        }
        els[0].value = value == null ? '' : String(value);
    }

    function fieldIsEmpty(form, name) {
        var el = form.querySelector('[name="' + name.replace(/"/g, '\\"') + '"]');
        if (!el) {
            return true;
        }
        if (el.type === 'radio') {
            var checked = form.querySelector('[name="' + name.replace(/"/g, '\\"') + '"]:checked');
            return !checked;
        }
        return String(el.value || '').trim() === '';
    }

    function applySnapshot(form, snap, onlyEmpty) {
        if (!snap || !snap.fields) {
            return;
        }
        Object.keys(snap.fields).forEach(function (name) {
            if (onlyEmpty && !fieldIsEmpty(form, name)) {
                return;
            }
            setFieldValue(form, name, snap.fields[name]);
        });
        if (snap.open_profile_pane && typeof snap.open_profile_pane === 'boolean') {
            var btnNext = document.getElementById('wizBtnNext');
            if (snap.open_profile_pane && btnNext) {
                btnNext.click();
            }
        }
    }

    function restorePasswords(form) {
        var pwd = readPwd();
        if (!pwd) {
            return;
        }
        var p1 = form.querySelector('#password');
        var p2 = form.querySelector('#password_confirm');
        if (p1 && !p1.value) {
            p1.value = pwd;
        }
        if (p2 && !p2.value) {
            p2.value = pwd;
        }
    }

    function collectExtra(form) {
        var extra = {};
        var paneP = document.getElementById('wizPaneProfile');
        if (paneP && paneP.style.display !== 'none') {
            extra.open_profile_pane = '1';
        }
        return extra;
    }

    function buildPayload(form, step) {
        var fields = formToObject(form);
        var extra = collectExtra(form);
        Object.keys(extra).forEach(function (k) {
            fields[k] = extra[k];
        });
        var pwdEl = form.querySelector('#password');
        var pwd2El = form.querySelector('#password_confirm');
        if (pwdEl && pwd2El) {
            var a = pwdEl.value || '';
            var b = pwd2El.value || '';
            if (a && a === b) {
                fields.password = a;
                writePwd(a);
            }
        }
        return {
            fields: fields,
            step: step,
            saved_at: new Date().toISOString(),
            open_profile_pane: extra.open_profile_pane === '1',
        };
    }

    function saveLocal(snapshot) {
        writeJson(storageKey(snapshot.step), snapshot);
    }

    function postAutosave(form, step, useBeacon) {
        var c = cfg();
        if (!c || !c.autosaveUrl || !c.csrf) {
            return Promise.resolve(false);
        }
        syncGeoHidden(form);
        syncPhones(form);
        var fd = new FormData(form);
        fd.set('install_action', 'wizard_autosave');
        fd.set('wizard_step', String(step));
        fd.set('csrf', c.csrf);
        var extra = collectExtra(form);
        Object.keys(extra).forEach(function (k) {
            fd.set(k, extra[k]);
        });
        var pwd = readPwd();
        var pwdEl = form.querySelector('#password');
        var pwd2El = form.querySelector('#password_confirm');
        if (pwdEl && pwd2El) {
            var a = pwdEl.value || '';
            var b = pwd2El.value || '';
            if (a && a === b) {
                fd.set('password', a);
                fd.set('password_confirm', b);
            } else if (pwd) {
                fd.set('password', pwd);
                fd.set('password_confirm', pwd);
            }
        }
        if (useBeacon && global.navigator && typeof global.navigator.sendBeacon === 'function') {
            try {
                global.navigator.sendBeacon(c.autosaveUrl, fd);
            } catch (e) {}
            return Promise.resolve(true);
        }
        return fetch(c.autosaveUrl, {
            method: 'POST',
            body: fd,
            credentials: 'same-origin',
            headers: { 'X-Requested-With': 'XMLHttpRequest', Accept: 'application/json' },
        })
            .then(function (r) {
                return r.json();
            })
            .then(function (data) {
                if (data && data.csrf) {
                    syncCsrfToken(data.csrf);
                }
                return !!(data && data.ok);
            })
            .catch(function () {
                return false;
            });
    }

    function scheduleSave(form, step, immediate) {
        if (!form) {
            return;
        }
        if (timer) {
            clearTimeout(timer);
            timer = null;
        }
        var run = function () {
            if (saving) {
                return;
            }
            saving = true;
            var snap = buildPayload(form, step);
            saveLocal(snap);
            postAutosave(form, step, false).finally(function () {
                saving = false;
            });
        };
        if (immediate) {
            run();
        } else {
            timer = setTimeout(run, DEBOUNCE_MS);
        }
    }

    function initForm(form, step) {
        if (!form) {
            return;
        }
        var localSnap = readJson(storageKey(step));
        var serverTs = (cfg() && cfg().draftUpdatedAt) || '';
        var localTs = (localSnap && localSnap.saved_at) || '';
        var preferLocal = localTs && (!serverTs || localTs > serverTs);
        if (localSnap && preferLocal) {
            applySnapshot(form, localSnap, false);
        } else if (localSnap) {
            applySnapshot(form, localSnap, true);
        }
        if (step === 2) {
            restorePasswords(form);
            scheduleSave(form, step, true);
        }
        form.addEventListener('input', function (ev) {
            var t = ev.target;
            if (t && (t.id === 'password' || t.id === 'password_confirm')) {
                var a = form.querySelector('#password');
                var b = form.querySelector('#password_confirm');
                if (a && b && a.value && a.value === b.value) {
                    writePwd(a.value);
                }
            }
            scheduleSave(form, step, false);
        });
        form.addEventListener('change', function () {
            scheduleSave(form, step, false);
        });
        form.addEventListener('submit', function () {
            scheduleSave(form, step, true);
        });
        global.addEventListener('beforeunload', function () {
            syncGeoHidden(form);
            syncPhones(form);
            postAutosave(form, step, true);
            saveLocal(buildPayload(form, step));
        });
        setInterval(function () {
            scheduleSave(form, step, true);
        }, PERIOD_MS);
        scheduleSave(form, step, true);
    }

    function restoreStep2SessionFromStorage() {
        var c = cfg();
        if (!c || parseInt(c.step, 10) !== 3) {
            return;
        }
        var pwd = readPwd();
        if (!pwd) {
            return;
        }
        var s2 = readJson(storageKey(2));
        var fd = new FormData();
        fd.set('install_action', 'wizard_autosave');
        fd.set('wizard_step', '2');
        fd.set('csrf', c.csrf);
        fd.set('access_mode', 'first_user');
        fd.set('password', pwd);
        fd.set('password_confirm', pwd);
        if (s2 && s2.fields) {
            ['email', 'username', 'phone'].forEach(function (k) {
                if (s2.fields[k]) {
                    fd.set(k, String(s2.fields[k]));
                }
            });
        }
        fetch(c.autosaveUrl, {
            method: 'POST',
            body: fd,
            credentials: 'same-origin',
            headers: { 'X-Requested-With': 'XMLHttpRequest', Accept: 'application/json' },
        }).catch(function () {});
    }

    function init() {
        meta = cfg();
        if (!meta || !meta.formId) {
            return;
        }
        if (meta.clearLocal) {
            clearLocalWizardStorage();
        }
        restoreStep2SessionFromStorage();
        var form = document.getElementById(meta.formId);
        if (!form) {
            return;
        }
        var step = parseInt(meta.step, 10) || 1;
        initForm(form, step);
        var btnNext = document.getElementById('wizBtnNext');
        var btnBack = document.getElementById('wizBtnBack');
        if (btnNext) {
            btnNext.addEventListener('click', function () {
                scheduleSave(form, step, true);
            });
        }
        if (btnBack) {
            btnBack.addEventListener('click', function () {
                scheduleSave(form, step, true);
            });
        }
        var addBranchBtn = document.getElementById('addBranchBtn');
        if (addBranchBtn) {
            addBranchBtn.addEventListener('click', function () {
                setTimeout(function () {
                    scheduleSave(form, step, true);
                }, 80);
            });
        }
    }

    global.InstallWizardPersist = {
        scheduleSave: function (immediate) {
            var c = cfg();
            if (!c || !c.formId) {
                return;
            }
            var form = document.getElementById(c.formId);
            if (!form) {
                return;
            }
            scheduleSave(form, parseInt(c.step, 10) || 1, !!immediate);
        },
    };

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})(typeof window !== 'undefined' ? window : this);
