// /AIWK_COMMON/core/aiwk_store.js
// AIWK v102-stage4.9-ext4-store-resize-noise-fix
(function () {
    "use strict";

    window.AIWK = window.AIWK || {};
    const AIWK = window.AIWK;
    const ROOT_KEY = "aiwk_ext4";
    const LEGACY_PREFIX = "aiwk_ext4_";

    function readRoot() {
        try {
            const raw = localStorage.getItem(ROOT_KEY);
            if (!raw) { return {}; }
            const obj = JSON.parse(raw);
            return obj && typeof obj === "object" && !Array.isArray(obj) ? obj : {};
        } catch (err) {
            return {};
        }
    }

    function rootSize(obj) {
        try { return new Blob([JSON.stringify(obj || {})]).size; } catch (err) { return String(JSON.stringify(obj || {})).length; }
    }

    function isLargeOrSensitiveKey(key) {
        return /LOG|TOKEN|PROFILE|VAULT|HISTORY|AUTH|PAYLOAD/i.test(String(key || ""));
    }

    function debugStore(tag, data) {
        try {
            if (AIWK.debug && typeof AIWK.debug.log === "function") {
                AIWK.debug.log(tag, data || {});
            }
        } catch (err) {}
    }

    function compactRoot(obj) {
        const root = obj && typeof obj === "object" && !Array.isArray(obj) ? Object.assign({}, obj) : {};
        [
            "AIWK_EXT4_RESULT_LOG",
            "AIWK_EXT4_DIALOG_LOG",
            "AIWK_ZIP_AUTO_APPLY_V1_LOG",
            "AIWK_CLIENT_PROFILE_VAULT",
            "AIWK_CLIENT_ID_HISTORY",
            "auth_token",
            "authToken",
            "profile",
            "auth_payload",
            "authPayload"
        ].forEach(function (k) { if (Object.prototype.hasOwnProperty.call(root, k)) delete root[k]; });
        Object.keys(root).forEach(function (k) {
            if (/LOG|TOKEN|PROFILE|VAULT|HISTORY/i.test(k) && rootSize({ v: root[k] }) > 2048) delete root[k];
        });
        return root;
    }

    function writeRoot(obj) {
        let root = compactRoot(obj || {});
        try {
            localStorage.setItem(ROOT_KEY, JSON.stringify(root));
            return root;
        } catch (err) {
            try {
                const minimal = { schema_version: "0.0.98", compacted_at: new Date().toISOString(), reason: "quota_compact" };
                localStorage.setItem(ROOT_KEY, JSON.stringify(minimal));
                debugStore("AIWK_STORE_COMPACTED", { key: ROOT_KEY, error: String(err && err.message || err), size: rootSize(root) });
                return minimal;
            } catch (e2) {
                try { console.error("[AIWK_STORE_WRITE_FAILED] " + JSON.stringify({ key: ROOT_KEY, error: String(e2 && e2.message || e2) })); } catch (e3) {}
                throw e2;
            }
        }
    }

    function legacyKey(name) {
        return LEGACY_PREFIX + String(name || "");
    }

    function legacyGet(name, fallbackValue) {
        try {
            const raw = localStorage.getItem(legacyKey(name));
            if (raw === null || raw === undefined || raw === "") { return fallbackValue; }
            return JSON.parse(raw);
        } catch (err) {
            return fallbackValue;
        }
    }

    function legacySet(name, value) {
        try { localStorage.setItem(legacyKey(name), JSON.stringify(value)); } catch (err) {}
    }

    function legacyRemove(name) {
        try { localStorage.removeItem(legacyKey(name)); } catch (err) {}
    }

    function get(name, fallbackValue) {
        const key = String(name || "");
        const root = readRoot();
        if (Object.prototype.hasOwnProperty.call(root, key)) {
            return root[key];
        }
        const old = legacyGet(key, undefined);
        if (old !== undefined) {
            // 개발 안정화: legacy 값을 읽더라도 token/profile/log류 대형 값은 root로 자동 이관하지 않는다.
            // 자동 이관 때문에 aiwk_ext4 quota compact가 반복되면 원인 추적이 어려워진다.
            if (!isLargeOrSensitiveKey(key) && rootSize({ v: old }) <= 2048) {
                root[key] = old;
                try { writeRoot(root); } catch (err) {}
            }
            return old;
        }
        return fallbackValue;
    }

    function set(name, value) {
        const key = String(name || "");
        const root = readRoot();
        root[key] = value;
        writeRoot(root);
        // v097: 긴 token/profile/log는 legacy 중복 저장하지 않는다.
        if (!isLargeOrSensitiveKey(key)) {
            legacySet(key, value);
        }
        return value;
    }

    function remove(name) {
        const key = String(name || "");
        const root = readRoot();
        if (Object.prototype.hasOwnProperty.call(root, key)) {
            delete root[key];
            writeRoot(root);
        }
        legacyRemove(key);
    }

    function cleanupVersionedKeys() {
        const removed = [];
        try {
            const root = readRoot();
            const keys = Object.keys(localStorage);
            keys.forEach(function (k) {
                if (!/^aiwk_ext4_(win_open_layout|win_all_state|win_restore_busy)_v\d+/i.test(k)) { return; }
                const short = k.replace(/^aiwk_ext4_/, "").replace(/_v\d+$/i, "");
                if (!Object.prototype.hasOwnProperty.call(root, short)) {
                    try {
                        const raw = localStorage.getItem(k);
                        if (raw) { root[short] = JSON.parse(raw); }
                    } catch (err) {}
                }
                localStorage.removeItem(k);
                removed.push(k);
            });
            writeRoot(root);
        } catch (err) {}
        return removed;
    }

    AIWK.store = {
        rootKey: ROOT_KEY,
        key: function (name) { return LEGACY_PREFIX + String(name || ""); },
        get: get,
        set: set,
        remove: remove,
        root: readRoot,
        saveRoot: writeRoot,
        cleanupVersionedKeys: cleanupVersionedKeys
    };

    try { cleanupVersionedKeys(); } catch (err) {}
}());
