/**
 * IndexedDB存储策略 - 修复复合索引问题
 */
class IndexedDBStorage {
  constructor(key) {
    this.key = key;
    this.dbName = 'hxhq';
    this.storeName = 'textContents';
    this.historyStoreName = 'textHistory';
    this.db = null;
    this.isInitialized = false;
    this.initPromise = this.initDB();
  }

  /**
   * 初始化IndexedDB数据库
   */
  async initDB() {
    return new Promise((resolve, reject) => {
      if (!window.indexedDB) {
        reject(new Error('浏览器不支持IndexedDB'));
        return;
      }

      const request = indexedDB.open(this.dbName, 5); // 升级版本到5

      request.onerror = (event) => {
        console.error('IndexedDB打开失败:', event.target.error);
        reject(event.target.error);
      };
      
      request.onsuccess = (event) => {
        this.db = event.target.result;
        this.isInitialized = true;
        console.log('IndexedDB初始化成功');
        
        // 延迟检查以确保事务完成
        setTimeout(() => {
          this.ensureStoresExist()
            .then(() => resolve())
            .catch(error => {
              console.warn('确保存储存在失败，但继续初始化:', error);
              resolve(); // 即使失败也继续
            });
        }, 100);
      };

      request.onupgradeneeded = (event) => {
        console.log('IndexedDB升级:', '旧版本:', event.oldVersion, '新版本:', event.newVersion);
        const db = event.target.result;
        const transaction = event.target.transaction;

        this.createOrUpgradeStores(db, transaction, event.oldVersion);
      };

      request.onblocked = (event) => {
        console.warn('IndexedDB升级被阻塞');
      };
    });
  }

  /**
   * 创建或升级对象存储（修复版）
   */
  createOrUpgradeStores(db, transaction, oldVersion) {
    // 创建主数据存储
    if (!db.objectStoreNames.contains(this.storeName)) {
      const store = db.createObjectStore(this.storeName, { keyPath: 'key' });
      store.createIndex('timestamp', 'timestamp', { unique: false });
      console.log('创建主存储:', this.storeName);
    }

    // 创建历史数据存储
    if (!db.objectStoreNames.contains(this.historyStoreName)) {
      const historyStore = db.createObjectStore(this.historyStoreName, { 
        keyPath: 'id',
        autoIncrement: true
      });
      historyStore.createIndex('timestamp', 'timestamp', { unique: false });
      historyStore.createIndex('key', 'key', { unique: false });
      // 不再创建唯一性复合索引，避免冲突
      console.log('创建历史存储:', this.historyStoreName);
    } else if (oldVersion < 5) {
      // 版本5升级：删除可能存在的唯一性索引，避免冲突
      const historyStore = transaction.objectStore(this.historyStoreName);
      
      // 删除旧的复合索引（如果存在）
      if (historyStore.indexNames.contains('key_version')) {
        try {
          historyStore.deleteIndex('key_version');
          console.log('删除冲突的key_version索引');
        } catch (error) {
          console.warn('删除索引失败:', error);
        }
      }
      
      // 添加非唯一的复合索引
      if (!historyStore.indexNames.contains('key_version_composite')) {
        try {
          historyStore.createIndex('key_version_composite', ['key', 'version'], { unique: false });
          console.log('创建非唯一的key_version_composite索引');
        } catch (error) {
          console.warn('创建非唯一索引失败:', error);
        }
      }
    }
  }

  /**
   * 确保对象存储存在
   */
  async ensureStoresExist() {
    if (!this.db) {
      throw new Error('数据库未初始化');
    }

    const missingStores = [this.storeName, this.historyStoreName]
      .filter(name => !this.db.objectStoreNames.contains(name));
    
    if (missingStores.length > 0) {
      console.warn('缺少对象存储:', missingStores);
      throw new Error(`缺少对象存储: ${missingStores.join(', ')}`);
    }
  }

  /**
   * 等待数据库初始化完成
   */
  async waitForInit() {
    try {
      await this.initPromise;
    } catch (error) {
      console.error('数据库初始化失败:', error);
      throw new Error('IndexedDB初始化失败: ' + error.message);
    }
    
    if (!this.isInitialized || !this.db) {
      throw new Error('数据库未正确初始化');
    }
  }

  /**
   * 保存数据到IndexedDB（修复版）
   */
  async save(content) {
    try {
      await this.waitForInit();
      const timestamp = Date.now();
      const version = await this.getNextVersion();

      const data = {
        key: this.key,
        content,
        timestamp,
        version,
        lastModified: timestamp
      };

      // 保存当前版本
      await this.putData(this.storeName, data);

      // 保存到历史记录 - 使用时间戳作为ID的一部分确保唯一性
      const historyId = `history_${this.key}_${timestamp}_${Math.random().toString(36).substr(2, 9)}`;
      const historyData = { 
        ...data, 
        id: historyId,
        historyTimestamp: timestamp,
        uniqueId: historyId // 确保唯一性
      };
      
      await this.putData(this.historyStoreName, historyData);

      return {
        success: true,
        timestamp,
        version,
        storage: 'indexedDB',
        historyId
      };
    } catch (error) {
      console.error('IndexedDB保存失败:', error);
      
      // 优雅降级到LocalStorage
      return await this.saveToFallback(content, error);
    }
  }

  /**
   * 保存到后备存储（LocalStorage）
   */
  async saveToFallback(content, originalError) {
    try {
      const timestamp = Date.now();
      const version = 1; // 后备存储使用简单版本号
      
      // 保存到LocalStorage
      const fallbackKey = `indexedDB_fallback_${this.key}`;
      localStorage.setItem(fallbackKey, JSON.stringify({
        content,
        timestamp,
        version,
        originalError: originalError?.message
      }));
      
      // 保存历史
      this.saveFallbackHistory(content, timestamp);
      
      return {
        success: true,
        timestamp,
        version,
        storage: 'indexedDB_fallback',
        warning: '数据已保存到LocalStorage作为后备',
        originalError: originalError?.message
      };
    } catch (fallbackError) {
      console.error('后备存储也失败:', fallbackError);
      return {
        success: false,
        error: `主存储和后备存储都失败: ${originalError?.message}, ${fallbackError.message}`,
        storage: 'indexedDB'
      };
    }
  }

  /**
   * 保存后备历史记录
   */
  saveFallbackHistory(content, timestamp) {
    try {
      const historyKey = `indexedDB_history_${this.key}`;
      const historyStr = localStorage.getItem(historyKey);
      let history = historyStr ? JSON.parse(historyStr) : [];
      
      history.unshift({
        content,
        timestamp,
        version: history.length + 1,
        fromFallback: true
      });
      
      // 限制历史记录数量
      if (history.length > 10) {
        history = history.slice(0, 10);
      }
      
      localStorage.setItem(historyKey, JSON.stringify(history));
    } catch (error) {
      console.error('保存后备历史失败:', error);
    }
  }

  /**
   * 将数据存入指定存储
   */
  async putData(storeName, data) {
    return new Promise((resolve, reject) => {
      try {
        // 检查对象存储是否存在
        if (!this.db.objectStoreNames.contains(storeName)) {
          reject(new Error(`对象存储 ${storeName} 不存在`));
          return;
        }

        const transaction = this.db.transaction([storeName], 'readwrite');
        const store = transaction.objectStore(storeName);
        
        // 添加错误处理
        transaction.onerror = (event) => {
          console.error(`事务错误 [${storeName}]:`, event.target.error);
          reject(event.target.error);
        };
        
        transaction.oncomplete = () => {
          resolve();
        };

        const request = store.put(data);

        request.onsuccess = () => {
          // 不要在这里resolve，等待事务完成
          console.log(`数据已保存到 ${storeName}:`, data.key);
        };
        
        request.onerror = (event) => {
          console.error(`保存请求失败 [${storeName}]:`, event.target.error);
          reject(event.target.error);
        };
      } catch (error) {
        reject(error);
      }
    });
  }

  /**
   * 从IndexedDB加载数据
   */
  async load() {
    try {
      await this.waitForInit();
      
      // 首先尝试从IndexedDB加载
      const data = await this.loadFromIndexedDB();
      if (data) {
        return {
          success: true,
          data,
          storage: 'indexedDB'
        };
      }
      
      // 如果没有数据，尝试从后备存储加载
      return await this.loadFromFallback();
      
    } catch (error) {
      console.error('加载数据失败:', error);
      return await this.loadFromFallbackWithError(error);
    }
  }

  /**
   * 从IndexedDB加载
   */
  async loadFromIndexedDB() {
    return new Promise((resolve, reject) => {
      try {
        if (!this.db.objectStoreNames.contains(this.storeName)) {
          resolve(null);
          return;
        }

        const transaction = this.db.transaction([this.storeName], 'readonly');
        const store = transaction.objectStore(this.storeName);
        const request = store.get(this.key);

        request.onsuccess = () => {
          resolve(request.result || null);
        };
        
        request.onerror = (event) => {
          console.error('从IndexedDB加载失败:', event.target.error);
          reject(event.target.error);
        };
      } catch (error) {
        reject(error);
      }
    });
  }

  /**
   * 从后备存储加载
   */
  async loadFromFallback() {
    try {
      const fallbackKey = `indexedDB_fallback_${this.key}`;
      const fallbackStr = localStorage.getItem(fallbackKey);
      
      if (fallbackStr) {
        const data = JSON.parse(fallbackStr);
        console.log('从后备存储加载数据');
        return {
          success: true,
          data,
          storage: 'indexedDB_fallback',
          fromFallback: true
        };
      }
      
      return {
        success: true,
        data: null,
        storage: 'indexedDB',
        message: '无数据'
      };
    } catch (error) {
      console.error('从后备存储加载失败:', error);
      return {
        success: false,
        error: error.message,
        storage: 'indexedDB_fallback'
      };
    }
  }

  /**
   * 带错误的从后备存储加载
   */
  async loadFromFallbackWithError(originalError) {
    try {
      const result = await this.loadFromFallback();
      if (result.success && result.data) {
        return {
          ...result,
          originalError: originalError?.message
        };
      }
      
      return {
        success: false,
        error: `加载失败: ${originalError?.message}`,
        storage: 'indexedDB'
      };
    } catch (error) {
      return {
        success: false,
        error: `主存储和后备存储都失败: ${originalError?.message}, ${error.message}`,
        storage: 'indexedDB'
      };
    }
  }

  /**
   * 获取历史版本（修复版）
   */
  async getHistory(limit = 100) {
    try {
      await this.waitForInit();
      
      // 首先尝试从IndexedDB获取历史
      const indexedDBHistory = await this.getHistoryFromIndexedDB(limit);
      if (indexedDBHistory.success && indexedDBHistory.data.length > 0) {
        return indexedDBHistory;
      }
      
      // 如果没有历史，尝试从后备存储获取
      return await this.getHistoryFromFallback(limit);
      
    } catch (error) {
      console.error('获取历史失败:', error);
      return await this.getHistoryFromFallback(limit);
    }
  }

  /**
   * 从IndexedDB获取历史
   */
  async getHistoryFromIndexedDB(limit) {
    return new Promise((resolve) => {
      try {
        if (!this.db.objectStoreNames.contains(this.historyStoreName)) {
          resolve({
            success: true,
            data: [],
            storage: 'indexedDB',
            message: '历史存储不存在'
          });
          return;
        }

        const transaction = this.db.transaction([this.historyStoreName], 'readonly');
        const store = transaction.objectStore(this.historyStoreName);
        
        // 尝试使用key索引
        let index;
        if (store.indexNames.contains('key')) {
          index = store.index('key');
        } else {
          // 如果没有key索引，使用全表扫描
          index = null;
        }
        
        const history = [];
        const request = index ? 
          index.openCursor(IDBKeyRange.only(this.key), 'prev') :
          store.openCursor(null, 'prev');

        request.onsuccess = (event) => {
          const cursor = event.target.result;
          if (cursor) {
            const item = cursor.value;
            // 过滤出当前key的历史记录
            if (item.key === this.key && history.length < limit) {
              history.push(item);
            }
            cursor.continue();
          } else {
            // 按时间戳排序
            history.sort((a, b) => b.timestamp - a.timestamp);
            resolve({
              success: true,
              data: history,
              storage: 'indexedDB'
            });
          }
        };
        
        request.onerror = (event) => {
          console.error('从IndexedDB获取历史失败:', event.target.error);
          resolve({
            success: false,
            error: event.target.error?.message,
            storage: 'indexedDB'
          });
        };
      } catch (error) {
        resolve({
          success: false,
          error: error.message,
          storage: 'indexedDB'
        });
      }
    });
  }

  /**
   * 从后备存储获取历史
   */
  async getHistoryFromFallback(limit) {
    try {
      const historyKey = `indexedDB_history_${this.key}`;
      const historyStr = localStorage.getItem(historyKey);
      const history = historyStr ? JSON.parse(historyStr) : [];
      
      return {
        success: true,
        data: history.slice(0, limit),
        storage: 'indexedDB_fallback',
        fromFallback: true
      };
    } catch (error) {
      return {
        success: false,
        error: error.message,
        storage: 'indexedDB_fallback'
      };
    }
  }

  /**
   * 获取下一个版本号
   */
  async getNextVersion() {
    try {
      const result = await this.load();
      if (result.success && result.data) {
        const data = result.data;
        return (data.version || 0) + 1;
      }
      return 1;
    } catch (error) {
      console.error('获取版本号失败:', error);
      return 1;
    }
  }

  /**
   * 清理重复的历史记录
   */
  async cleanupDuplicateHistory() {
    try {
      await this.waitForInit();
      
      if (!this.db.objectStoreNames.contains(this.historyStoreName)) {
        return { success: true, cleaned: 0 };
      }

      return new Promise((resolve) => {
        const transaction = this.db.transaction([this.historyStoreName], 'readwrite');
        const store = transaction.objectStore(this.historyStoreName);
        
        // 找出当前key的所有历史记录
        const index = store.index('key');
        const keyRange = IDBKeyRange.only(this.key);
        const request = index.openCursor(keyRange);
        
        const seenVersions = new Set();
        const duplicates = [];
        const toDelete = [];

        request.onsuccess = (event) => {
          const cursor = event.target.result;
          if (cursor) {
            const item = cursor.value;
            const versionKey = `${item.key}_${item.version}`;
            
            if (seenVersions.has(versionKey)) {
              duplicates.push(item);
              toDelete.push(item.id);
            } else {
              seenVersions.add(versionKey);
            }
            cursor.continue();
          } else {
            // 删除重复项
            if (toDelete.length === 0) {
              resolve({ success: true, cleaned: 0, duplicates: [] });
              return;
            }
            
            this.deleteHistoryItems(toDelete)
              .then(() => {
                console.log(`清理了 ${toDelete.length} 条重复历史记录`);
                resolve({ 
                  success: true, 
                  cleaned: toDelete.length, 
                  duplicates: duplicates.map(d => ({ id: d.id, version: d.version }))
                });
              })
              .catch(error => {
                resolve({ 
                  success: false, 
                  error: error.message,
                  duplicatesFound: duplicates.length
                });
              });
          }
        };
        
        request.onerror = (event) => {
          resolve({
            success: false,
            error: event.target.error?.message
          });
        };
      });
    } catch (error) {
      return {
        success: false,
        error: error.message
      };
    }
  }

  /**
   * 删除历史记录项
   */
  async deleteHistoryItems(ids) {
    return new Promise((resolve, reject) => {
      const transaction = this.db.transaction([this.historyStoreName], 'readwrite');
      const store = transaction.objectStore(this.historyStoreName);
      
      let completed = 0;
      let errors = [];
      
      ids.forEach(id => {
        const request = store.delete(id);
        request.onerror = (event) => {
          errors.push({ id, error: event.target.error });
        };
      });
      
      transaction.oncomplete = () => {
        if (errors.length > 0) {
          reject(new Error(`删除失败: ${errors.map(e => e.error.message).join(', ')}`));
        } else {
          resolve();
        }
      };
      
      transaction.onerror = (event) => {
        reject(event.target.error);
      };
    });
  }

  /**
   * 重置数据库（用于修复）
   */
  async resetDatabase() {
    try {
      // 备份现有数据
      const backup = await this.load();
      
      // 关闭当前连接
      if (this.db) {
        this.db.close();
      }
      
      // 删除数据库
      await new Promise((resolve, reject) => {
        const deleteRequest = indexedDB.deleteDatabase(this.dbName);
        deleteRequest.onsuccess = () => resolve();
        deleteRequest.onerror = (event) => reject(event.target.error);
      });
      
      console.log('数据库已重置');
      
      // 重新初始化
      this.db = null;
      this.isInitialized = false;
      this.initPromise = this.initDB();
      await this.waitForInit();
      
      // 恢复数据（如果有）
      if (backup.success && backup.data) {
        await this.save(backup.data.content);
      }
      
      return { 
        success: true, 
        message: '数据库重置成功',
        dataRestored: backup.success && !!backup.data
      };
    } catch (error) {
      console.error('重置数据库失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }
}
export default IndexedDBStorage;