import { getCurrentDateTime, getTimestamp } from './dateUtils'

// 数据库配置
const DB_NAME = 'SmartisanNoteDB'
const DB_VERSION = 2 // 更新版本号以确保数据库重新创建
const NOTES_STORE = 'notes'
const FOLDERS_STORE = 'folders'
const SETTINGS_STORE = 'settings'

let db = null

/**
 * 打开数据库连接
 * @returns {Promise<IDBDatabase>} 数据库实例
 */
const openDB = () => {
  return new Promise((resolve, reject) => {
    if (db) {
      return resolve(db)
    }

    const request = indexedDB.open(DB_NAME, DB_VERSION)

    request.onerror = () => {
      reject(new Error('无法打开数据库'))
    }

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

    request.onupgradeneeded = (event) => {
      const database = event.target.result

      // 删除现有的对象存储（如果版本已更改）
      if (event.oldVersion > 0) {
        if (database.objectStoreNames.contains(NOTES_STORE)) {
          database.deleteObjectStore(NOTES_STORE)
        }
        if (database.objectStoreNames.contains(FOLDERS_STORE)) {
          database.deleteObjectStore(FOLDERS_STORE)
        }
        if (database.objectStoreNames.contains(SETTINGS_STORE)) {
          database.deleteObjectStore(SETTINGS_STORE)
        }
      }

      // 创建便签存储对象
      const notesStore = database.createObjectStore(NOTES_STORE, { keyPath: 'id' })
      notesStore.createIndex('folderId', 'folderId', { unique: false })
      notesStore.createIndex('isStarred', 'isStarred', { unique: false })
      notesStore.createIndex('isDeleted', 'isDeleted', { unique: false })
      notesStore.createIndex('createdAt', 'createdAt', { unique: false })
      notesStore.createIndex('updatedAt', 'updatedAt', { unique: false })

      // 创建文件夹存储对象
      database.createObjectStore(FOLDERS_STORE, { keyPath: 'id' })

      // 创建设置存储对象
      database.createObjectStore(SETTINGS_STORE)
    }
  })
}

/**
 * 从存储中获取数据
 * @param {string} storeName - 存储名称
 * @returns {Promise<Array>} 数据数组
 */
const getAllFromStore = async (storeName) => {
  const database = await openDB()
  const transaction = database.transaction([storeName], 'readonly')
  const store = transaction.objectStore(storeName)
  const request = store.getAll()

  return new Promise((resolve, reject) => {
    request.onsuccess = () => {
      resolve(request.result || [])
    }

    request.onerror = () => {
      reject(new Error(`获取 ${storeName} 数据失败`))
    }
  })
}

/**
 * 保存数据到存储
 * @param {string} storeName - 存储名称
 * @param {Array} data - 要保存的数据数组
 * @returns {Promise<void>}
 */
const saveToStore = async (storeName, data) => {
  const database = await openDB()
  const transaction = database.transaction([storeName], 'readwrite')
  const store = transaction.objectStore(storeName)

  // 清除现有数据
  await new Promise((resolve, reject) => {
    const clearRequest = store.clear()
    clearRequest.onsuccess = () => resolve()
    clearRequest.onerror = () => reject(new Error(`清除 ${storeName} 数据失败`))
  })

  // 添加新数据
  for (const item of data) {
    await new Promise((resolve, reject) => {
      const addRequest = store.add(item)
      addRequest.onsuccess = () => resolve()
      addRequest.onerror = () => reject(new Error(`保存 ${storeName} 数据失败`))
    })
  }
}

/**
 * 从存储中获取单个项
 * @param {string} storeName - 存储名称
 * @param {string} id - 项的ID
 * @returns {Promise<Object|null>} 项对象或null
 */
const getFromStore = async (storeName, id) => {
  const database = await openDB()
  const transaction = database.transaction([storeName], 'readonly')
  const store = transaction.objectStore(storeName)
  const request = store.get(id)

  return new Promise((resolve, reject) => {
    request.onsuccess = () => {
      resolve(request.result || null)
    }

    request.onerror = () => {
      reject(new Error(`获取 ${storeName} 项失败`))
    }
  })
}

/**
 * 向存储中添加项
 * @param {string} storeName - 存储名称
 * @param {Object} item - 要添加的项
 * @returns {Promise<Object>} 添加的项
 */
const addToStore = async (storeName, item) => {
  const database = await openDB()
  const transaction = database.transaction([storeName], 'readwrite')
  const store = transaction.objectStore(storeName)
  const request = store.add(item)

  return new Promise((resolve, reject) => {
    request.onsuccess = () => {
      resolve(item)
    }

    request.onerror = () => {
      reject(new Error(`添加 ${storeName} 项失败`))
    }
  })
}

/**
 * 更新存储中的项
 * @param {string} storeName - 存储名称
 * @param {string} id - 项的ID
 * @param {Object} updates - 要更新的属性对象
 * @returns {Promise<Object|null>} 更新后的项或null
 */
const updateInStore = async (storeName, id, updates) => {
  const item = await getFromStore(storeName, id)
  if (!item) return null

  const updatedItem = { ...item, ...updates }
  const database = await openDB()
  const transaction = database.transaction([storeName], 'readwrite')
  const store = transaction.objectStore(storeName)
  const request = store.put(updatedItem)

  return new Promise((resolve, reject) => {
    request.onsuccess = () => {
      resolve(updatedItem)
    }

    request.onerror = () => {
      reject(new Error(`更新 ${storeName} 项失败`))
    }
  })
}

/**
 * 从存储中删除项
 * @param {string} storeName - 存储名称
 * @param {string} id - 要删除的项的ID
 * @returns {Promise<boolean>} 删除成功返回true，失败返回false
 */
const deleteFromStore = async (storeName, id) => {
  const database = await openDB()
  const transaction = database.transaction([storeName], 'readwrite')
  const store = transaction.objectStore(storeName)
  const request = store.delete(id)

  return new Promise((resolve, reject) => {
    request.onsuccess = () => {
      resolve(true)
    }

    request.onerror = () => {
      reject(new Error(`删除 ${storeName} 项失败`))
    }
  })
}

// 便签操作函数
// 提供便签的增删改查功能

/**
 * 获取所有便签数据
 * 从IndexedDB中读取便签数据
 * @returns {Promise<Array>} 便签数组
 */
export const getNotes = async () => {
  try {
    const notes = await getAllFromStore(NOTES_STORE)
    return ensureNotesDefaults(notes)
  } catch (error) {
    console.error('Error getting notes:', error)
    return []
  }
}

/**
 * 保存便签数据
 * 将便签数组保存到IndexedDB
 * @param {Array} notes - 便签数组
 * @returns {Promise<void>}
 */
export const saveNotes = async (notes) => {
  try {
    await saveToStore(NOTES_STORE, notes)
  } catch (error) {
    console.error('Error saving notes:', error)
  }
}

/**
 * 添加新便签
 * 创建一个新的便签对象并添加到便签列表中
 * @param {Object} note - 便签对象，包含便签内容和其他属性
 * @returns {Promise<Object>} 新创建的便签对象
 */
export const addNote = async (note) => {
  try {
    // 创建新的便签对象，添加必要的属性
    const newNote = {
      title: note.title || '',
      content: note.content || '',
      id: note.id || getTimestamp().toString(), // 使用时间戳生成唯一ID
      createdAt: note.createdAt || getCurrentDateTime(), // 创建时间
      updatedAt: note.updatedAt || getCurrentDateTime(), // 更新时间
      isStarred: note.isStarred || false, // 是否加星
      isTop: note.isTop || false, // 是否置顶
      hasImage: note.hasImage || false, // 是否包含图片
      isDeleted: note.isDeleted || false, // 是否已删除
      deletedAt: note.deletedAt || null, // 删除时间
      folderId: note.folderId || null, // 文件夹ID
      ...note
    }

    // 添加到存储
    await addToStore(NOTES_STORE, newNote)
    return newNote
  } catch (error) {
    console.error('Error adding note:', error)
    throw error
  }
}

/**
 * 更新便签
 * 根据ID查找并更新便签信息
 * @param {string} id - 便签ID
 * @param {Object} updates - 要更新的属性对象
 * @returns {Promise<Object|null>} 更新后的便签对象，如果未找到则返回null
 */
export const updateNote = async (id, updates) => {
  try {
    // 更新便签并保存
    const updatedNote = await updateInStore(NOTES_STORE, id, {
      ...updates,
      updatedAt: getCurrentDateTime() // 更新最后修改时间
    })

    return updatedNote
  } catch (error) {
    console.error('Error updating note:', error)
    throw error
  }
}

/**
 * 删除便签
 * 根据ID从便签列表中移除便签
 * @param {string} id - 要删除的便签ID
 * @returns {Promise<boolean>} 删除成功返回true，未找到便签返回false
 */
export const deleteNote = async (id) => {
  try {
    // 从存储中删除
    const result = await deleteFromStore(NOTES_STORE, id)
    return result
  } catch (error) {
    console.error('Error deleting note:', error)
    return false
  }
}

// 文件夹操作函数
// 提供文件夹的增删改查功能

/**
 * 获取所有文件夹数据
 * 从IndexedDB中读取文件夹数据
 * @returns {Promise<Array>} 文件夹数组
 */
export const getFolders = async () => {
  try {
    const folders = await getAllFromStore(FOLDERS_STORE)
    return ensureFoldersDefaults(folders)
  } catch (error) {
    console.error('Error getting folders:', error)
    return []
  }
}

/**
 * 保存文件夹数据
 * 将文件夹数组保存到IndexedDB
 * @param {Array} folders - 文件夹数组
 * @returns {Promise<void>}
 */
export const saveFolders = async (folders) => {
  try {
    await saveToStore(FOLDERS_STORE, folders)
  } catch (error) {
    console.error('Error saving folders:', error)
  }
}

/**
 * 添加新文件夹
 * 创建一个新的文件夹对象并添加到文件夹列表中
 * @param {Object} folder - 文件夹对象，包含文件夹名称等属性
 * @returns {Promise<Object>} 新创建的文件夹对象
 */
export const addFolder = async (folder) => {
  try {
    // 创建新的文件夹对象，添加必要的属性
    const newFolder = {
      name: folder.name || '',
      id: folder.id || getTimestamp().toString(), // 使用时间戳生成唯一ID
      createdAt: folder.createdAt || getCurrentDateTime(), // 创建时间
      ...folder
    }

    // 添加到存储
    await addToStore(FOLDERS_STORE, newFolder)
    return newFolder
  } catch (error) {
    console.error('Error adding folder:', error)
    throw error
  }
}

// 设置操作函数
// 提供应用设置的读取和保存功能

/**
 * 获取应用设置
 * 从IndexedDB中读取设置数据
 * @returns {Promise<Object>} 设置对象，如果读取失败则返回默认设置
 */
export const getSettings = async () => {
  try {
    const database = await openDB()
    const transaction = database.transaction([SETTINGS_STORE], 'readonly')
    const store = transaction.objectStore(SETTINGS_STORE)
    const request = store.get('settings')

    const settings = await new Promise((resolve, reject) => {
      request.onsuccess = () => {
        resolve(request.result || { cloudSync: false, darkMode: false })
      }

      request.onerror = () => {
        reject(new Error('获取设置失败'))
      }
    })

    return settings
  } catch (error) {
    console.error('Error getting settings:', error)
    // 出错时返回默认设置
    return { cloudSync: false, darkMode: false }
  }
}

/**
 * 保存应用设置
 * 将设置对象保存到IndexedDB
 * @param {Object} settings - 设置对象
 * @returns {Promise<void>}
 */
export const saveSettings = async (settings) => {
  try {
    const database = await openDB()
    const transaction = database.transaction([SETTINGS_STORE], 'readwrite')
    const store = transaction.objectStore(SETTINGS_STORE)
    const request = store.put(settings, 'settings')

    await new Promise((resolve, reject) => {
      request.onsuccess = () => resolve()
      request.onerror = () => reject(new Error('保存设置失败'))
    })
  } catch (error) {
    console.error('Error saving settings:', error)
  }
}

/**
 * 确保数据有默认值
 * @param {Array} notes - 便签数组
 * @returns {Array} 处理后的便签数组
 */
const ensureNotesDefaults = (notes) => {
  return notes.map(note => ({
    title: note.title || '',
    content: note.content || '',
    id: note.id,
    createdAt: note.createdAt,
    updatedAt: note.updatedAt,
    isStarred: note.isStarred || false,
    isTop: note.isTop || false,
    hasImage: note.hasImage || false,
    isDeleted: note.isDeleted || false,
    deletedAt: note.deletedAt || null,
    folderId: note.folderId || null,
    ...note
  }))
}

/**
 * 确保文件夹数据有默认值
 * @param {Array} folders - 文件夹数组
 * @returns {Array} 处理后的文件夹数组
 */
const ensureFoldersDefaults = (folders) => {
  return folders.map(folder => ({
    name: folder.name || '',
    id: folder.id,
    createdAt: folder.createdAt,
    ...folder
  }))
}

/**
 * 初始化数据库
 * @returns {Promise<void>}
 */
export const initDB = async () => {
  try {
    await openDB()
  } catch (error) {
    console.error('Error initializing database:', error)
  }
}