import { SystemConfig, Novel, Chapter } from '../types';

const DB_NAME = 'AINovelDB';
const DB_VERSION = 2;

class IndexedDBStorage {
  private db: IDBDatabase | null = null;

  async init(): Promise<void> {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(DB_NAME, DB_VERSION);

      request.onerror = () => {
        reject(new Error('Failed to open IndexedDB'));
      };

      request.onsuccess = () => {
        this.db = request.result;
        resolve();
      };

      request.onupgradeneeded = (event) => {
        const db = (event.target as IDBOpenDBRequest).result;

        // 创建小说存储
        if (!db.objectStoreNames.contains('novels')) {
          const novelStore = db.createObjectStore('novels', { keyPath: 'id' });
          novelStore.createIndex('createdAt', 'createdAt', { unique: false });
        }

        // 创建章节存储
        if (!db.objectStoreNames.contains('chapters')) {
          const chapterStore = db.createObjectStore('chapters', { keyPath: 'id' });
          chapterStore.createIndex('novelId', 'novelId', { unique: false });
          chapterStore.createIndex('chapterNumber', 'chapterNumber', { unique: false });
        }

        // 创建系统配置存储
        if (!db.objectStoreNames.contains('config')) {
          db.createObjectStore('config', { keyPath: 'id' });
        }
      };
    });
  }

  private async getStore(storeName: string, mode: IDBTransactionMode = 'readonly'): Promise<IDBObjectStore> {
    if (!this.db) {
      await this.init();
    }
    
    // 如果数据库连接失败，尝试重新初始化
    if (!this.db) {
      throw new Error('Database initialization failed');
    }
    
    // 检查请求的存储是否存在
    if (!this.db.objectStoreNames.contains(storeName)) {
      console.error(`Object store '${storeName}' not found in database`);
      // 尝试重新初始化数据库以创建缺失的存储
      await this.reinit();
      if (!this.db || !this.db.objectStoreNames.contains(storeName)) {
        throw new Error(`Object store '${storeName}' not found after reinitialization`);
      }
    }
    
    const transaction = this.db.transaction(storeName, mode);
    return transaction.objectStore(storeName);
  }

  private async reinit(): Promise<void> {
    // 关闭当前连接
    if (this.db) {
      this.db.close();
      this.db = null;
    }
    
    // 删除旧数据库并重新创建
    return new Promise((resolve, reject) => {
      const deleteReq = indexedDB.deleteDatabase(DB_NAME);
      deleteReq.onsuccess = () => {
        console.log('Old database deleted successfully');
        this.init().then(resolve).catch(reject);
      };
      deleteReq.onerror = () => {
        console.error('Failed to delete old database');
        reject(new Error('Failed to delete old database'));
      };
    });
  }


  // 小说操作
  async getNovels(): Promise<Novel[]> {
    const store = await this.getStore('novels');
    return new Promise((resolve, reject) => {
      const request = store.getAll();
      request.onsuccess = () => resolve(request.result || []);
      request.onerror = () => reject(request.error);
    });
  }

  async addNovel(novel: Novel): Promise<void> {
    const store = await this.getStore('novels', 'readwrite');
    return new Promise((resolve, reject) => {
      const request = store.add(novel);
      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  }

  async updateNovel(id: string, updates: Partial<Novel>): Promise<void> {
    const novels = await this.getNovels();
    const index = novels.findIndex(n => n.id === id);
    if (index !== -1) {
      const updatedNovel = { ...novels[index], ...updates, updatedAt: new Date().toISOString() };
      const store = await this.getStore('novels', 'readwrite');
      return new Promise((resolve, reject) => {
        const request = store.put(updatedNovel);
        request.onsuccess = () => resolve();
        request.onerror = () => reject(request.error);
      });
    }
  }

  async deleteNovel(id: string): Promise<void> {
    const store = await this.getStore('novels', 'readwrite');
    return new Promise((resolve, reject) => {
      const request = store.delete(id);
      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  }

  // 章节操作
  async getChapters(novelId: string): Promise<Chapter[]> {
    const store = await this.getStore('chapters');
    return new Promise((resolve, reject) => {
      const request = store.getAll();
      request.onsuccess = () => {
        const allChapters = request.result || [];
        resolve(allChapters.filter(c => c.novelId === novelId));
      };
      request.onerror = () => reject(request.error);
    });
  }

  async getAllChapters(): Promise<Chapter[]> {
    const store = await this.getStore('chapters');
    return new Promise((resolve, reject) => {
      const request = store.getAll();
      request.onsuccess = () => resolve(request.result || []);
      request.onerror = () => reject(request.error);
    });
  }

  async addChapter(chapter: Chapter): Promise<void> {
    const store = await this.getStore('chapters', 'readwrite');
    return new Promise((resolve, reject) => {
      const request = store.add(chapter);
      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  }

  async updateChapter(id: string, updates: Partial<Chapter>): Promise<void> {
    const chapters = await this.getAllChapters();
    const index = chapters.findIndex(c => c.id === id);
    if (index !== -1) {
      const updatedChapter = { ...chapters[index], ...updates, updatedAt: new Date().toISOString() };
      const store = await this.getStore('chapters', 'readwrite');
      return new Promise((resolve, reject) => {
        const request = store.put(updatedChapter);
        request.onsuccess = () => resolve();
        request.onerror = () => reject(request.error);
      });
    }
  }

  async deleteChapter(id: string): Promise<void> {
    const store = await this.getStore('chapters', 'readwrite');
    return new Promise((resolve, reject) => {
      const request = store.delete(id);
      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  }

  // 系统配置操作
  async getSystemConfig(): Promise<SystemConfig> {
    const store = await this.getStore('config');
    return new Promise((resolve) => {
      const request = store.get('system');
      request.onsuccess = () => {
        const config = request.result;
        if (config) {
          delete config.id;
          resolve(config);
        } else {
          // 返回默认配置
          resolve({
            ollamaUrl: 'http://localhost:11434',
            model: '',
            temperature: 0.7,
            topP: 0.9,
            maxTokens: 2000
          });
        }
      };
      request.onerror = () => {
        resolve({
          ollamaUrl: 'http://localhost:11434',
          model: '',
          temperature: 0.7,
          topP: 0.9,
          maxTokens: 2000
        });
      };
    });
  }

  async saveSystemConfig(config: SystemConfig): Promise<void> {
    const store = await this.getStore('config', 'readwrite');
    const data = { id: 'system', ...config };
    return new Promise((resolve, reject) => {
      const request = store.put(data);
      request.onsuccess = () => resolve();
      request.onerror = () => reject(request.error);
    });
  }
}

// 导出单例
export const indexedDBStorage = new IndexedDBStorage();

// 调试工具：检查数据库状态
export const debugDB = async () => {
  try {
    await indexedDBStorage.init();
    const novels = await indexedDBStorage.getNovels();
    const chapters = await indexedDBStorage.getAllChapters();
    const config = await indexedDBStorage.getSystemConfig();
    
    console.log('=== IndexedDB 调试信息 ===');
    console.log('小说数量:', novels.length);
    console.log('章节数量:', chapters.length);
    console.log('系统配置:', config);
    console.log('========================');
    
    return {
      novels,
      chapters,
      config,
      status: 'success'
    };
  } catch (error) {
    console.error('IndexedDB 调试失败:', error);
    return {
      status: 'error',
      error: error instanceof Error ? error.message : 'Unknown error'
    };
  }
};

// 兼容旧代码的 storage 对象
export const storage = {
  getNovels: () => indexedDBStorage.getNovels(),
  addNovel: (novel: Novel) => indexedDBStorage.addNovel(novel),
  updateNovel: (id: string, updates: Partial<Novel>) => indexedDBStorage.updateNovel(id, updates),
  deleteNovel: (id: string) => indexedDBStorage.deleteNovel(id),
  
  getChapters: (novelId: string) => indexedDBStorage.getChapters(novelId),
  getAllChapters: () => indexedDBStorage.getAllChapters(),
  addChapter: (chapter: Chapter) => indexedDBStorage.addChapter(chapter),
  updateChapter: (id: string, updates: Partial<Chapter>) => indexedDBStorage.updateChapter(id, updates),
  deleteChapter: (id: string) => indexedDBStorage.deleteChapter(id),
  
  getSystemConfig: () => indexedDBStorage.getSystemConfig(),
  saveSystemConfig: (config: SystemConfig) => indexedDBStorage.saveSystemConfig(config)
};