/**
 * Flexia — detecta nueva instancia/instalación y borra persistencia local obsoleta.
 * Debe cargarse antes que main.js u otros scripts que lean localStorage.
 */
(function (global) {
    'use strict';

    var LS_GEN_KEY = 'flexia_client_install_generation_v1';
    var SS_PENDING_WIPE = 'flexia_pending_client_wipe';

    var LS_PREFIXES = [
        'grid_',
        'flexia_',
        'antara',
        'antara:',
        'grid_auth_fallback_',
        'zoom_device_id_v1',
        'iframeZoom_',
    ];

    var LS_EXACT_KEYS = ['gridDesktopRecoverCount', 'gridShowRecoverBtn'];

    var SS_PREFIXES = ['grid_', 'flexia_', 'antara'];

    function shouldRemoveLsKey(key) {
        if (!key || key === LS_GEN_KEY) {
            return false;
        }
        var i;
        for (i = 0; i < LS_PREFIXES.length; i++) {
            if (key.indexOf(LS_PREFIXES[i]) === 0) {
                return true;
            }
        }
        for (i = 0; i < LS_EXACT_KEYS.length; i++) {
            if (key === LS_EXACT_KEYS[i]) {
                return true;
            }
        }
        return false;
    }

    function hasPersistenceEvidence() {
        try {
            var i;
            for (i = 0; i < localStorage.length; i++) {
                var k = localStorage.key(i);
                if (k && shouldRemoveLsKey(k)) {
                    return true;
                }
            }
        } catch (_) {}
        return false;
    }

    function wipeClientPersistence() {
        var keys = [];
        var i;
        try {
            for (i = 0; i < localStorage.length; i++) {
                var k = localStorage.key(i);
                if (k && shouldRemoveLsKey(k)) {
                    keys.push(k);
                }
            }
        } catch (_) {}
        keys.forEach(function (key) {
            try {
                localStorage.removeItem(key);
            } catch (_) {}
        });

        try {
            for (i = sessionStorage.length - 1; i >= 0; i--) {
                var sk = sessionStorage.key(i);
                if (!sk) {
                    continue;
                }
                var remove = false;
                for (var j = 0; j < SS_PREFIXES.length; j++) {
                    if (sk.indexOf(SS_PREFIXES[j]) === 0) {
                        remove = true;
                        break;
                    }
                }
                if (remove) {
                    sessionStorage.removeItem(sk);
                }
            }
        } catch (_) {}
    }

    function readStoredGeneration() {
        try {
            return localStorage.getItem(LS_GEN_KEY);
        } catch (_) {
            return null;
        }
    }

    function storeGeneration(generation) {
        try {
            localStorage.setItem(LS_GEN_KEY, generation);
        } catch (_) {}
    }

    function hasPendingWipeFlag() {
        try {
            return sessionStorage.getItem(SS_PENDING_WIPE) === '1';
        } catch (_) {
            return false;
        }
    }

    function clearPendingWipeFlag() {
        try {
            sessionStorage.removeItem(SS_PENDING_WIPE);
        } catch (_) {}
    }

    function markPendingWipe() {
        try {
            sessionStorage.setItem(SS_PENDING_WIPE, '1');
        } catch (_) {}
    }

    function resolveInstanceApiUrl() {
        if (global.BASE_URL) {
            return String(global.BASE_URL).replace(/\/?$/, '/') + 'index.php?action=flexiaInstance';
        }
        if (global.FLEXIA_INSTANCE_GUARD && global.FLEXIA_INSTANCE_GUARD.apiUrl) {
            return global.FLEXIA_INSTANCE_GUARD.apiUrl;
        }
        return 'index.php?action=flexiaInstance';
    }

    function runGuard(serverGeneration, options) {
        options = options || {};
        if (!serverGeneration) {
            return false;
        }
        var prevGen = readStoredGeneration();
        var pendingWipe = options.forcePending || hasPendingWipeFlag();
        var shouldWipe = false;

        if (hasPersistenceEvidence()) {
            if (pendingWipe) {
                shouldWipe = true;
            } else if (prevGen && prevGen !== serverGeneration) {
                shouldWipe = true;
            }
        }

        if (shouldWipe) {
            wipeClientPersistence();
            clearPendingWipeFlag();
        }

        storeGeneration(serverGeneration);
        return shouldWipe;
    }

    function pollInstanceGeneration() {
        var knownGen = readStoredGeneration();
        if (!knownGen) {
            return;
        }

        function check() {
            fetch(resolveInstanceApiUrl(), { credentials: 'same-origin', cache: 'no-store' })
                .then(function (res) {
                    return res.json();
                })
                .then(function (data) {
                    if (!data || !data.generation || data.generation === knownGen) {
                        return;
                    }
                    var wiped = runGuard(String(data.generation), { forcePending: hasPendingWipeFlag() });
                    if (wiped) {
                        knownGen = String(data.generation);
                        try {
                            global.location.reload();
                        } catch (_) {}
                    } else {
                        knownGen = String(data.generation);
                    }
                })
                .catch(function () {});
        }

        if (global.document && typeof global.document.addEventListener === 'function') {
            global.document.addEventListener('visibilitychange', function () {
                if (global.document.visibilityState === 'visible') {
                    check();
                }
            });
        }
        global.setInterval(check, 120000);
    }

    var inst = global.FLEXIA_INSTANCE;
    if (inst && inst.generation) {
        runGuard(String(inst.generation));
        if (global.FLEXIA_INSTANCE_GUARD && global.FLEXIA_INSTANCE_GUARD.poll !== false) {
            pollInstanceGeneration();
        }
    }

    global.FlexiaInstanceGuard = {
        LS_GEN_KEY: LS_GEN_KEY,
        SS_PENDING_WIPE: SS_PENDING_WIPE,
        hasPersistenceEvidence: hasPersistenceEvidence,
        wipeClientPersistence: wipeClientPersistence,
        runGuard: runGuard,
        markPendingWipe: markPendingWipe,
    };
})(typeof window !== 'undefined' ? window : this);
