class IndexedDBHelper {
    constructor(dbName, version = 1) {
        this.dbName = dbName;
        this.version = version;
        this.db = null;
    }

    /**
     * 初始化数据库（打开/创建）
     * @param {Array} stores [{ name: "storeName", keyPath: "id", indexes: [{ name: "indexName", key: "keyPath", unique: false }] }]
     * @returns {Promise}
     */
    openDB(stores = []) {
        return new Promise((resolve, reject) => {
            const request = indexedDB.open(this.dbName, this.version);

            request.onupgradeneeded = (event) => {
                this.db = event.target.result;
                stores.forEach(store => {
                    if (!this.db.objectStoreNames.contains(store.name)) {
                        const objectStore = this.db.createObjectStore(store.name, {
                            keyPath: store.keyPath,
                            autoIncrement: store.autoIncrement || false
                        });
                        if (store.indexes) {
                            store.indexes.forEach(index => {
                                objectStore.createIndex(index.name, index.key, {
                                    unique: index.unique
                                });
                            });
                        }
                    }

                });
            };

            request.onsuccess = (event) => {
                this.db = event.target.result;
                console.log("✅ IndexedDB 连接成功");
                resolve(this.db);
            };

            request.onerror = (event) => {
                reject(`IndexedDB Error: ${event.target.error}`);
            };
        });
    }

    // 通用查询方法，按指定字段查询
    async queryByField(storeName, fieldName, value) {
        return new Promise(async (resolve, reject) => {
            try {
                if (!this.db) {
                    await this.openDB();
                }
                const transaction = this.db.transaction(storeName, 'readonly');
                const store = transaction.objectStore(storeName);

                if (!store.indexNames.contains(fieldName)) {
                    return reject(`索引 ${fieldName} 不存在`);
                }

                const index = store.index(fieldName);
                const request = index.getAll(value);

                request.onsuccess = (event) => {
                    resolve(event.target.result);
                };

                request.onerror = (event) => {
                    reject('查询失败: ' + event.target.error);
                };
            } catch (error) {
                reject('查询错误: ' + error);
            }
        });
    }

    /**
     * 添加数据（支持单条或批量）
     * @param {string} storeName - 存储空间名称
     * @param {Object|Array} data - 要添加的数据（单条对象或数组）
     * @returns {Promise<number|Array<number>>} - 返回添加数据的ID（单条返回数字，批量返回数组）
     */
    add(storeName, data) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction([storeName], "readwrite");
            const store = transaction.objectStore(storeName);

            // 统一处理为数组格式
            const items = Array.isArray(data) ? data : [data];
            const results = [];

            // 监听每个添加操作的成功事件
            items.forEach((item, index) => {
                const request = store.add(item);
                request.onsuccess = (event) => {
                    results[index] = event.target.result; // 保存生成的ID
                };
                request.onerror = (event) => {
                    transaction.abort(); // 遇到错误时中止事务
                    reject(`第 ${index + 1} 条数据添加失败: ${event.target.error}`);
                };
            });

            // 监听事务完成事件
            transaction.oncomplete = () => {
                // 单条数据返回单个ID，批量返回数组
                resolve(items.length === 1 ? results[0] : results);
            };

            // 统一错误处理
            transaction.onerror = (event) => {
                reject(`添加失败: ${event.target.error}`);
            };
        });
    }

    /**
     * 读取数据（根据主键）
     * @param {string} storeName
     * @param {any} key
     * @returns {Promise}
     */
    get(storeName, key) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction([storeName], "readonly");
            const store = transaction.objectStore(storeName);
            const request = store.get(key);

            request.onsuccess = () => resolve(request.result);
            request.onerror = (event) => reject(`Get Error: ${event.target.error}`);
        });
    }

    /**
     * 读取所有数据（兼容X5内核方案）
     * @param {string} storeName
     * @returns {Promise}
     */
    getAll(storeName) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction([storeName], "readonly");
            const store = transaction.objectStore(storeName);

            // 兼容性检测：优先尝试原生getAll方法
            if (typeof store.getAll === 'function') {
                const request = store.getAll();
                request.onsuccess = () => resolve(request.result);
                request.onerror = (e) => reject(`GetAll Error: ${e.target.error}`);
            }
            // 降级方案：使用游标手动遍历
            else {
                const results = [];
                const request = store.openCursor();

                request.onsuccess = (e) => {
                    const cursor = e.target.result;
                    if (cursor) {
                        results.push(cursor.value);
                        cursor.continue();
                    } else {
                        resolve(results);
                    }
                };

                request.onerror = (e) => reject(`Cursor Error: ${e.target.error}`);
            }
        });
    }

    /**
     * 获取表的总记录数
     * @param {string} storeName - 表名（Object Store 名称）
     * @returns {Promise<number>} - 记录总数
     */
    async getRecordCount(storeName) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction([storeName], "readonly");
            const store = transaction.objectStore(storeName);
            const request = store.count();

            request.onsuccess = () => resolve(request.result);
            request.onerror = (event) => reject(`❌ Count Error: ${event.target.error}`);
        });
    }

    /**
     * 更新数据（支持指定 key 或自动使用 keyPath）
     * @param {string} storeName 存储对象名
     * @param {Object} data 待更新数据
     * @param {IDBValidKey|IDBKeyRange} [key] 可选参数，指定更新的 key
     * @returns {Promise<string>} 更新结果
     */
    update(storeName, data, key) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction([storeName], "readwrite");
            const store = transaction.objectStore(storeName);
            const keyPath = store.keyPath;

            // 有传入 key：直接使用 key 更新
            if (key !== undefined) {
                const request = store.put(data, key);
                request.onsuccess = () => resolve("数据更新成功（指定 key）");
                request.onerror = (event) => reject(`更新失败: ${event.target.error}`);
                return;
            }

            // 无传入 key：依赖 keyPath 更新
            if (!keyPath) {
                reject("当前 store 未设置 keyPath，必须传入 key 参数");
                return;
            }

            // 检查数据是否包含 keyPath 属性
            let missingKeys = [];
            if (Array.isArray(keyPath)) {
                missingKeys = keyPath.filter(k => !data.hasOwnProperty(k));
            } else if (typeof keyPath === 'string') {
                if (!data.hasOwnProperty(keyPath)) {
                    missingKeys.push(keyPath);
                }
            }

            if (missingKeys.length > 0) {
                reject(`数据缺少必要的 keyPath 属性: ${missingKeys.join(', ')}`);
                return;
            }

            // 默认使用 keyPath 更新
            const request = store.put(data);
            request.onsuccess = () => resolve("数据更新成功（默认 keyPath）");
            request.onerror = (event) => reject(`更新失败: ${event.target.error}`);
        });
    }

    /**
     * 删除数据（根据主键）
     * @param {string} storeName
     * @param {any} key
     * @returns {Promise}
     */
    delete(storeName, key) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction([storeName], "readwrite");
            const store = transaction.objectStore(storeName);
            const request = store.delete(key);

            request.onsuccess = () => resolve("Data deleted successfully");
            request.onerror = (event) => reject(`Delete Error: ${event.target.error}`);
        });
    }
    /**
     * 根据条件删除所有匹配的数据
     * @param {string} storeName - 数据仓库名
     * @param {function} conditionFn - 判断是否删除 (record) => boolean
     * @returns {Promise}
     */
    deleteByCondition(storeName, conditionFn) {
        return new Promise((resolve, reject) => {
            if (!this.db) {
                reject('Database not initialized');
                return;
            }

            const transaction = this.db.transaction([storeName], 'readwrite');
            const store = transaction.objectStore(storeName);
            const request = store.openCursor();

            request.onsuccess = (event) => {
                const cursor = event.target.result;
                if (cursor && cursor.value) {
                    try {
                        // console.log(cursor.value)
                        const shouldDelete = conditionFn(cursor.value);
                        if (shouldDelete) {
                            cursor.delete();
                        }
                    } catch (err) {
                        console.error('Condition function error:', err);
                    }
                    cursor.continue();
                } else {
                    resolve('All matching records deleted successfully');
                }
            };

            request.onerror = (event) => {
                reject(`Delete by condition failed: ${event.target.error}`);
            };
        });
    }

    /**
     * 通过索引查询数据
     * @param {string} storeName
     * @param {string} indexName
     * @param {any} value
     * @returns {Promise}
     */
    getByIndex(storeName, indexName, value) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction([storeName], "readonly");
            const store = transaction.objectStore(storeName);
            const index = store.index(indexName);
            const request = index.get(value);

            request.onsuccess = () => resolve(request.result);
            request.onerror = (event) => reject(`Get By Index Error: ${event.target.error}`);
        });
    }

    /**
     * 清空表
     * @param {string} storeName
     * @returns {Promise}
     */
    clearStore(storeName) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction([storeName], "readwrite");
            const store = transaction.objectStore(storeName);
            const request = store.clear();

            request.onsuccess = () => resolve("Store cleared successfully");
            request.onerror = (event) => reject(`Clear Store Error: ${event.target.error}`);
        });
    }

    /**
     * 删除数据库
     * @returns {Promise}
     */
    deleteDB(dbNamed = null) {
        return new Promise((resolve, reject) => {
            const request = indexedDB.deleteDatabase(dbNamed || this.dbName);

            request.onsuccess = () => resolve("Database deleted successfully");
            request.onerror = (event) => reject(`Delete DB Error: ${event.target.error}`);
        });
    }

    async deleteOldestRecord(storeName) {
        return new Promise((resolve, reject) => {
            const transaction = this.db.transaction([storeName], "readwrite");
            const store = transaction.objectStore(storeName);
            const request = store.openCursor(); // 🔹 获取最早的记录（按主键 ID 排序）

            request.onsuccess = function(event) {
                const cursor = event.target.result;
                if (cursor) {
                    console.log(`🗑️ 删除最早的记录 ID: ${cursor.key}`);
                    store.delete(cursor.key); // 🔥 删除最小 ID（最早记录）
                    resolve();
                } else {
                    resolve(); // 没有记录时跳过
                }
            };

            request.onerror = (event) => reject(`❌ Cursor Error: ${event.target.error}`);
        });
    }
}

export default IndexedDBHelper