import globalConfig from '@/config';
import { createSessionStorage, decryptKey, StorageOptions } from '@/utils/storage';

/**
 * 创建 sessionStorage 工具实例
 * @see 在 src/utils/storage 的基础上，添加了命名空间，如果 encryptKey 为 false，能有效避免多个应用在同一个域名下的数据冲突。
 * @param opts {StorageOptions} 本实例使用的全局配置
 * @returns
 */
function createSessionTools(storageOptions: StorageOptions = {}) {
    const ss = createSessionStorage(storageOptions);

    /**
     * 保存数据
     * @param key
     * @param value
     * @param opts 当传递了 opts 时，opts 中存在的配置项会覆盖当前实例的全局配置中的配置项。
     */
    function setSession<T = any>(key: string, value: T, opts?: StorageOptions) {
        ss.set<T>(`${globalConfig.app.storageNameSpace}${key}`, value, opts);
    }

    /**
     * 读取数据
     * @param key
     * @param opts 当传递了 opts 时，opts 中存在的配置项会覆盖当前实例的全局配置中的配置项。
     * @returns
     */
    function getSession<T>(key: string, opts?: StorageOptions) {
        return ss.get<T>(`${globalConfig.app.storageNameSpace}${key}`, opts);
    }

    /**
     * 删除数据
     * @param key
     * @param opts 当传递了 opts 时，opts 中存在的配置项会覆盖当前实例的全局配置中的配置项。
     */
    function removeSession(key: string, opts?: StorageOptions) {
        ss.remove(`${globalConfig.app.storageNameSpace}${key}`, opts);
    }

    /**
     * 清除 sessionStorage 中的所有数据。**慎用**
     */
    function clearSession() {
        const removedKeys = [];

        for (let i = 0; i < window.sessionStorage.length; i++) {
            const key = window.sessionStorage.key(i);
            if (!key) continue;

            // 先检查原始 key 是否属于当前命名空间
            if (key.startsWith(globalConfig.app.storageNameSpace)) {
                removedKeys.push(key);
                continue;
            }

            // 如果不是，尝试解密后检查是否属于当前命名空间
            const decryptedKey = decryptKey(key);
            if (decryptedKey && decryptedKey.startsWith(globalConfig.app.storageNameSpace)) {
                removedKeys.push(key);
            }
        }

        // 删除所有匹配的 key
        for (const key of removedKeys) {
            ss.remove(key, { encryptKey: false });
        }
    }

    return { setSession, getSession, removeSession, clearSession };
}

const secureSessionStorage = createSessionTools({ encryptKey: true, encryptData: true });

export { createSessionTools, secureSessionStorage };
