import { AllEnums, ErrorInfos } from '@/services/http/system/interface';

// 数据库表名 所有枚举信息 | 数据库错误信息
type ObjectStoreName = 'AllEnums' | 'ErrorInfos';
// 读取操作类型
type ReadType = 'readwrite' | 'readonly';
// 错误枚举 索引名
const ErrorEnumIndexName = 'autoid';
const AllEnumIndexName = 'enumdicid';

const DBReqest = indexedDB.open('_IndexDB_');
let db: IDBDatabase;

DBReqest.onerror = (err) => {
    console.error(`数据库打开报错: ${err}`);
};
DBReqest.onsuccess = () => {
    console.log(`数据库打开成功`);
    db = DBReqest.result;
};
// 新建数据库与打开数据库是同一个操作。如果指定的数据库不存在，就会新建。
// 不同之处在于，后续的操作主要在upgradeneeded事件的监听函数里面完成，因为这时版本从无到有，所以会触发这个事件。
DBReqest.onupgradeneeded = (event: any) => {
    db = event.target.reesult;
    console.log(`数据库更新成功`);
    if (!hasDB('AllEnums')) {
        // 所有枚举信息
        const allEnusm = db.createObjectStore('AllEnums', { keyPath: 'autoid' });
        // 建立索引
        allEnusm.createIndex('errorid', AllEnumIndexName);
    }
    if (!hasDB('ErrorInfos')) {
        // 数据库错误信息
        const allEnusm = db.createObjectStore('ErrorInfos', { keyPath: 'rowNumber' });
        // 建立索引
        allEnusm.createIndex('errorid', ErrorEnumIndexName);
    }
};

/**
 * 是否存在某张表
 * @param stroeName ObjectStoreName
 * @returns boolean
 */
function hasDB(stroeName: ObjectStoreName): boolean {
    return db.objectStoreNames.contains(stroeName);
}

/**
 * 获取 某张表
 * @param stroeName 数据库表名 ObjectStoreName
 * @returns IDBObjectStore
 */
function getObjectStore(stroeName: ObjectStoreName, readType: ReadType): IDBObjectStore {
    const temp = db.transaction([stroeName], readType);
    return temp.objectStore(stroeName);
}

/**
 * 添加数据
 * @param stroeName 数据库表名 ObjectStoreName
 * @param list 添加的数据
 */
function add(stroeName: ObjectStoreName, list: AllEnums[] | ErrorInfos[]) {
    const request = getObjectStore(stroeName, 'readwrite');
    // 批量添加
    for (let i = 0; i < list.length; i++) {
        const item = list[i];
        request.add(item);
    }
}
/**
 * 删除数据
 * @param stroeName 数据库表名 ObjectStoreName
 */
function remove(stroeName: ObjectStoreName) {
    const request = getObjectStore(stroeName, 'readwrite');
    const result = request.delete(1);
    result.onsuccess = (event) => {
        console.log('数据删除成功');
    };
    result.onerror = (event) => {
        console.log('数据删除失败');
    };
}
function get(stroeName: ObjectStoreName, id: number) {
    const request = getObjectStore(stroeName, 'readonly');
    const indexName = stroeName === 'ErrorInfos' ? ErrorEnumIndexName : AllEnumIndexName;
    const index = request.index(indexName);
    const result = index.get(id);
    result.onsuccess = (event: any) => {
        console.log('数据读取成功', event.target.result);
    };
    result.onerror = () => {
        console.log('数据读取失败');
    };
    return result;
}

// class IndexDB {
//     private name: string;
//     private db: IDBDatabase;

//     constructor(name: string) {
//         const request = indexedDB.open(name);
//         // this.db = request.result;

//         request.onerror = err => {
//             console.error(`${name}数据库打开报错: ${err}`);
//         }
//         request.onsuccess = () => {
//             console.log(`${name}数据库打开成功`);
//             this.db = request.result;
//         }
//         // 新建数据库与打开数据库是同一个操作。如果指定的数据库不存在，就会新建。
//         // 不同之处在于，后续的操作主要在upgradeneeded事件的监听函数里面完成，因为这时版本从无到有，所以会触发这个事件。
//         request.onupgradeneeded = (event: any) => {
//             this.db = event.target.reesult;
//             console.log(`${name}数据库更新成功`);
//             if (!this.hasDB('AllEnums')) { // 所有枚举信息
//                 const allEnusm = this.db.createObjectStore('AllEnums', {keyPath: 'autoid'})
//                 // 建立索引
//                 allEnusm.createIndex('errorid', AllEnumIndexName)
//             }
//             if (!this.hasDB('ErrorInfos')) { // 数据库错误信息
//                 const allEnusm = this.db.createObjectStore('ErrorInfos', {keyPath: 'rowNumber'})
//                 // 建立索引
//                 allEnusm.createIndex('errorid', ErrorEnumIndexName)
//             }
//         }
//         this.name = name;
//     }
//     /**
//      * 添加数据
//      * @param stroeName 数据库表名 ObjectStoreName
//      * @param list 添加的数据
//      */
//     add(stroeName: ObjectStoreName, list: AllEnums[] | ErrorInfos[]) {
//         const request = this.getObjectStore(stroeName, 'readwrite')
//         // 批量添加
//         for(let i = 0; i < list.length; i++) {
//             const item = list[i];
//             request.add(item)
//         }
//     }
//     /**
//      * 删除数据
//      * @param stroeName 数据库表名 ObjectStoreName
//      */
//     remove(stroeName: ObjectStoreName) {
//         const request = this.getObjectStore(stroeName, 'readwrite')
//         const result = request.delete(1);
//         result.onsuccess = (event) => {
//             console.log('数据删除成功');
//         };
//         result.onerror = (event) =>  {
//             console.log('数据删除失败');
//         }
//     }
//     get(stroeName: ObjectStoreName, id: number) {
//         const request = this.getObjectStore(stroeName, 'readonly')
//         const indexName = stroeName === 'ErrorInfos' ? ErrorEnumIndexName : AllEnumIndexName;
//         const index = request.index(indexName)
//         const result = index.get(id);
//         result.onsuccess = (event: any) => {
//             console.log('数据读取成功',event.target.result);
//         }
//         result.onerror = () => {
//             console.log('数据读取失败');

//         }
//         return result;
//     }
//     /**
//      * 是否存在某张表
//      * @param stroeName ObjectStoreName
//      * @returns boolean
//      */
//     private hasDB(stroeName: ObjectStoreName): boolean {
//         return this.db.objectStoreNames.contains(stroeName)
//     }
//     /**
//      * 获取 某张表
//      * @param stroeName 数据库表名 ObjectStoreName
//      * @returns IDBObjectStore
//      */
//     private getObjectStore(stroeName: ObjectStoreName, readType: ReadType): IDBObjectStore {
//         return this.db.transaction([stroeName], readType).objectStore(stroeName)
//     }
// }
// const IndexedDB = new IndexDB('_IndexDB_')
// export default IndexedDB;
const DB = { add, get, remove };
export default DB;
