// uni-storage-helper.js
class UniStorageHelper {
    constructor(dbName, options = {}) {
        this.dbName = dbName;
        this.storesMeta = {};
        this.options = {
            maxEntries: 500, // 单个存储空间最大条目数
            maxSizeMB: 1, // 单条数据最大限制（微信小程序限制）
            autoPurge: true, // 是否自动清理旧数据
            purgeBatch: 10, // 自动清理批次数量
            debug: false, // 调试模式
            ...options
        };
    }

    /*==================
     核心方法
    ==================*/

    /**
     * 初始化存储空间
     * @param {Array} stores - 存储空间配置
     */
    async openDB(stores = []) {
        stores.forEach(store => {
            const storeKey = this._getStoreKey(store.name);
            if (!this._storageHas(storeKey)) {
                this._storageSet(storeKey, []);
            }

            this.storesMeta[store.name] = {
                keyPath: store.keyPath,
                autoIncrement: !!store.autoIncrement,
                indexes: store.indexes || []
            };

            if (store.autoIncrement) {
                const counterKey = this._getCounterKey(store.name);
                if (!this._storageHas(counterKey)) {
                    this._storageSet(counterKey, 1);
                }
            }
        });

        this._log('数据库初始化完成');
        return Promise.resolve();
    }

    /**
     * 添加数据（自动处理容量限制）
     */
    async add(storeName, data) {
        try {
            const storeKey = this._getStoreKey(storeName);
            let storeData = this._storageGet(storeKey) || [];
            const meta = this.storesMeta[storeName];
            const items = Array.isArray(data) ? data : [data];

            // 容量预检
            await this._checkCapacity(storeName, items);

            // 处理自增ID
            if (meta?.autoIncrement) {
                const counterKey = this._getCounterKey(storeName);
                let nextId = this._storageGet(counterKey) || 1;
                items.forEach(item => {
                    item[meta.keyPath] = nextId++;
                    this._createIndexes(meta.indexes, item);
                });
                this._storageSet(counterKey, nextId);
            }

            // 保存数据
            storeData = [...storeData, ...items];
            this._storageSet(storeKey, storeData);

            this._log(`成功添加${items.length}条数据到${storeName}`);

            return meta?.autoIncrement ?
                Array.isArray(data) ?
                items.map(i => i[meta.keyPath]) :
                items[0][meta.keyPath] :
                undefined;

        } catch (error) {
            if (error.message.includes('exceed')) {
                this._log('触发自动清理...');
                await this._purgeData(storeName, this.options.purgeBatch);
                return this.add(storeName, data);
            }
            throw error;
        }
    }

    /*==================
     查询方法
    ==================*/

    async get(storeName, key) {
        const storeData = this._storageGet(this._getStoreKey(storeName)) || [];
        const keyPath = this.storesMeta[storeName]?.keyPath;
        return storeData.find(item => item[keyPath] === key);
    }

    async getAll(storeName) {
        return this._storageGet(this._getStoreKey(storeName)) || [];
    }

    async queryByField(storeName, fieldName, value) {
        const storeData = this._storageGet(this._getStoreKey(storeName)) || [];
        return storeData.filter(item => item[fieldName] === value);
    }

    async getRecordCount(storeName) {
        const storeData = this._storageGet(this._getStoreKey(storeName)) || [];
        return storeData.length;
    }

    async deleteOldestRecord(storeName) {
        const storeKey = this._getStoreKey(storeName);
        const storeData = this._storageGet(storeKey) || [];
        if (storeData.length > 0) {
            // 删除第一条记录（最早的记录）
            const newData = storeData.slice(1);
            this._storageSet(storeKey, newData);
            this._log(`删除最早的记录，剩余${newData.length}条记录`);
        }
        return Promise.resolve();
    }

    /*==================
     更新/删除方法
    ==================*/

    async update(storeName, data, key) {
        const storeKey = this._getStoreKey(storeName);
        const storeData = this._storageGet(storeKey) || [];
        const meta = this.storesMeta[storeName];
        const keyPath = meta?.keyPath;
        const targetKey = key ?? data[keyPath];

        const index = storeData.findIndex(item => item[keyPath] === targetKey);
        if (index === -1) throw new Error('未找到对应记录');

        // 合并数据并重建索引
        const newItem = {
            ...storeData[index],
            ...data
        };
        this._createIndexes(meta.indexes, newItem);

        storeData[index] = newItem;
        this._storageSet(storeKey, storeData);

        return "更新成功";
    }

    async delete(storeName, key) {
        const storeKey = this._getStoreKey(storeName);
        const storeData = this._storageGet(storeKey) || [];
        const keyPath = this.storesMeta[storeName]?.keyPath;
        const newData = storeData.filter(item => item[keyPath] !== key);
        this._storageSet(storeKey, newData);
        return `删除${storeData.length - newData.length}条记录`;
    }

    /*==================
     存储管理
    ==================*/

    async clearStore(storeName) {
        this._storageSet(this._getStoreKey(storeName), []);
        return "存储空间已清空";
    }

    async deleteDB() {
        Object.keys(this.storesMeta).forEach(storeName => {
            uni.removeStorageSync(this._getStoreKey(storeName));
            uni.removeStorageSync(this._getCounterKey(storeName));
        });
        return "数据库已删除";
    }

    /*==================
     私有方法
    ==================*/

    _getStoreKey(storeName) {
        return `${this.dbName}_${storeName}`;
    }

    _getCounterKey(storeName) {
        return `${this.dbName}_${storeName}_counter`;
    }

    _createIndexes(indexes, item) {
        indexes.forEach(index => {
            item[index.name] = item[index.key];
        });
    }

    async _checkCapacity(storeName, newItems) {
        const storeKey = this._getStoreKey(storeName);
        const currentData = this._storageGet(storeKey) || [];

        // 检查条目数限制
        if (currentData.length + newItems.length > this.options.maxEntries) {
            await this._purgeData(storeName, newItems.length);
        }

        // 检查单条数据大小
        newItems.forEach(item => {
            const sizeMB = this._getItemSizeMB(item);
            if (sizeMB > this.options.maxSizeMB) {
                throw new Error(`单条数据大小超出${this.options.maxSizeMB}MB限制`);
            }
        });
    }

    _getItemSizeMB(item) {
        try {
            // 精确计算（支持Blob的环境）
            return new Blob([JSON.stringify(item)]).size / 1024 / 1024;
        } catch {
            // 兼容方案
            return encodeURIComponent(JSON.stringify(item)).length * 2 / 1024 / 1024;
        }
    }

    async _purgeData(storeName, count) {
        const storeKey = this._getStoreKey(storeName);
        const currentData = this._storageGet(storeKey) || [];
        const newData = currentData.slice(count);
        this._storageSet(storeKey, newData);
        this._log(`自动清理${count}条旧数据`);
    }

    /*==================
     存储适配器
    ==================*/

    _storageHas(key) {
        return !!uni.getStorageSync(key);
    }

    _storageGet(key) {
        try {
            return uni.getStorageSync(key);
        } catch (e) {
            return null;
        }
    }

    _storageSet(key, value) {
        try {
            uni.setStorageSync(key, value);
            return true;
        } catch (error) {
            if (error.errMsg?.includes('exceed')) {
                throw new Error('STORAGE_QUOTA_EXCEEDED');
            }
            throw error;
        }
    }

    _log(...args) {
        if (this.options.debug) {
            console.log(`[StorageHelper]`, ...args);
        }
    }
}

export default UniStorageHelper;