/**
 * 本地存储工具类
 * 提供统一的本地存储接口，支持同步和异步操作
 */

// 存储键名常量
export const STORAGE_KEYS = {
  // 用户相关
  USER_TOKEN: 'user_token',
  USER_INFO: 'user_info',
  USER_SETTINGS: 'user_settings',
  
  // 应用配置
  APP_CONFIG: 'app_config',
  APP_VERSION: 'app_version',
  LANGUAGE: 'language',
  THEME: 'theme',
  
  // 业务数据
  SEARCH_HISTORY: 'search_history',
  BROWSE_HISTORY: 'browse_history',
  FAVORITES: 'favorites',
  CART_DATA: 'cart_data',
  FORM_DRAFT: 'form_draft',
  
  // 缓存数据
  API_CACHE: 'api_cache',
  IMAGE_CACHE: 'image_cache',
  LOCATION_CACHE: 'location_cache'
}

// 存储配置
const STORAGE_CONFIG = {
  // 默认过期时间（毫秒）
  DEFAULT_EXPIRE_TIME: 7 * 24 * 60 * 60 * 1000, // 7天
  // 最大存储条目数
  MAX_ITEMS: 1000,
  // 存储大小限制（字节）
  MAX_SIZE: 10 * 1024 * 1024, // 10MB
  // 键名前缀
  KEY_PREFIX: 'xlxumu_'
}

/**
 * 存储项包装器
 */
class StorageItem {
  constructor(value, options = {}) {
    this.value = value
    this.timestamp = Date.now()
    this.expireTime = options.expireTime || null
    this.version = options.version || '1.0.0'
    this.metadata = options.metadata || {}
  }

  /**
   * 检查是否过期
   */
  isExpired() {
    if (!this.expireTime) return false
    return Date.now() > this.timestamp + this.expireTime
  }

  /**
   * 获取剩余有效时间
   */
  getRemainingTime() {
    if (!this.expireTime) return Infinity
    return Math.max(0, this.timestamp + this.expireTime - Date.now())
  }

  /**
   * 序列化为JSON
   */
  toJSON() {
    return {
      value: this.value,
      timestamp: this.timestamp,
      expireTime: this.expireTime,
      version: this.version,
      metadata: this.metadata
    }
  }

  /**
   * 从JSON反序列化
   */
  static fromJSON(json) {
    const item = new StorageItem(json.value)
    item.timestamp = json.timestamp
    item.expireTime = json.expireTime
    item.version = json.version || '1.0.0'
    item.metadata = json.metadata || {}
    return item
  }
}

/**
 * 存储管理器类
 */
class StorageManager {
  constructor(options = {}) {
    this.config = { ...STORAGE_CONFIG, ...options }
    this.cache = new Map() // 内存缓存
  }

  /**
   * 生成完整的存储键名
   */
  getFullKey(key) {
    return `${this.config.KEY_PREFIX}${key}`
  }

  /**
   * 同步设置存储项
   */
  setSync(key, value, options = {}) {
    try {
      const fullKey = this.getFullKey(key)
      const item = new StorageItem(value, {
        expireTime: options.expireTime || this.config.DEFAULT_EXPIRE_TIME,
        version: options.version,
        metadata: options.metadata
      })

      const serialized = JSON.stringify(item.toJSON())
      
      // 检查存储大小
      if (serialized.length > this.config.MAX_SIZE) {
        throw new Error('存储项过大')
      }

      uni.setStorageSync(fullKey, serialized)
      
      // 更新内存缓存
      this.cache.set(key, item)
      
      return true
    } catch (error) {
      console.error('存储设置失败:', error)
      return false
    }
  }

  /**
   * 异步设置存储项
   */
  async set(key, value, options = {}) {
    return new Promise((resolve, reject) => {
      try {
        const fullKey = this.getFullKey(key)
        const item = new StorageItem(value, {
          expireTime: options.expireTime || this.config.DEFAULT_EXPIRE_TIME,
          version: options.version,
          metadata: options.metadata
        })

        const serialized = JSON.stringify(item.toJSON())
        
        // 检查存储大小
        if (serialized.length > this.config.MAX_SIZE) {
          throw new Error('存储项过大')
        }

        uni.setStorage({
          key: fullKey,
          data: serialized,
          success: () => {
            // 更新内存缓存
            this.cache.set(key, item)
            resolve(true)
          },
          fail: (error) => {
            console.error('存储设置失败:', error)
            reject(error)
          }
        })
      } catch (error) {
        console.error('存储设置失败:', error)
        reject(error)
      }
    })
  }

  /**
   * 同步获取存储项
   */
  getSync(key, defaultValue = null) {
    try {
      // 先检查内存缓存
      if (this.cache.has(key)) {
        const item = this.cache.get(key)
        if (!item.isExpired()) {
          return item.value
        } else {
          // 过期则删除
          this.cache.delete(key)
          this.removeSync(key)
        }
      }

      const fullKey = this.getFullKey(key)
      const serialized = uni.getStorageSync(fullKey)
      
      if (!serialized) {
        return defaultValue
      }

      const itemData = JSON.parse(serialized)
      const item = StorageItem.fromJSON(itemData)

      // 检查是否过期
      if (item.isExpired()) {
        this.removeSync(key)
        return defaultValue
      }

      // 更新内存缓存
      this.cache.set(key, item)
      
      return item.value
    } catch (error) {
      console.error('存储获取失败:', error)
      return defaultValue
    }
  }

  /**
   * 异步获取存储项
   */
  async get(key, defaultValue = null) {
    return new Promise((resolve) => {
      try {
        // 先检查内存缓存
        if (this.cache.has(key)) {
          const item = this.cache.get(key)
          if (!item.isExpired()) {
            resolve(item.value)
            return
          } else {
            // 过期则删除
            this.cache.delete(key)
            this.remove(key)
          }
        }

        const fullKey = this.getFullKey(key)
        
        uni.getStorage({
          key: fullKey,
          success: (res) => {
            try {
              const itemData = JSON.parse(res.data)
              const item = StorageItem.fromJSON(itemData)

              // 检查是否过期
              if (item.isExpired()) {
                this.remove(key)
                resolve(defaultValue)
                return
              }

              // 更新内存缓存
              this.cache.set(key, item)
              
              resolve(item.value)
            } catch (error) {
              console.error('存储数据解析失败:', error)
              resolve(defaultValue)
            }
          },
          fail: () => {
            resolve(defaultValue)
          }
        })
      } catch (error) {
        console.error('存储获取失败:', error)
        resolve(defaultValue)
      }
    })
  }

  /**
   * 同步删除存储项
   */
  removeSync(key) {
    try {
      const fullKey = this.getFullKey(key)
      uni.removeStorageSync(fullKey)
      this.cache.delete(key)
      return true
    } catch (error) {
      console.error('存储删除失败:', error)
      return false
    }
  }

  /**
   * 异步删除存储项
   */
  async remove(key) {
    return new Promise((resolve) => {
      try {
        const fullKey = this.getFullKey(key)
        
        uni.removeStorage({
          key: fullKey,
          success: () => {
            this.cache.delete(key)
            resolve(true)
          },
          fail: (error) => {
            console.error('存储删除失败:', error)
            resolve(false)
          }
        })
      } catch (error) {
        console.error('存储删除失败:', error)
        resolve(false)
      }
    })
  }

  /**
   * 检查存储项是否存在
   */
  hasSync(key) {
    try {
      const fullKey = this.getFullKey(key)
      const value = uni.getStorageSync(fullKey)
      return !!value
    } catch (error) {
      return false
    }
  }

  /**
   * 异步检查存储项是否存在
   */
  async has(key) {
    return new Promise((resolve) => {
      const fullKey = this.getFullKey(key)
      
      uni.getStorage({
        key: fullKey,
        success: () => resolve(true),
        fail: () => resolve(false)
      })
    })
  }

  /**
   * 获取存储项信息
   */
  getInfoSync(key) {
    try {
      const fullKey = this.getFullKey(key)
      const serialized = uni.getStorageSync(fullKey)
      
      if (!serialized) {
        return null
      }

      const itemData = JSON.parse(serialized)
      const item = StorageItem.fromJSON(itemData)

      return {
        key,
        size: serialized.length,
        timestamp: item.timestamp,
        expireTime: item.expireTime,
        remainingTime: item.getRemainingTime(),
        isExpired: item.isExpired(),
        version: item.version,
        metadata: item.metadata
      }
    } catch (error) {
      console.error('获取存储信息失败:', error)
      return null
    }
  }

  /**
   * 获取所有存储键名
   */
  getAllKeysSync() {
    try {
      const info = uni.getStorageInfoSync()
      const prefix = this.config.KEY_PREFIX
      
      return info.keys
        .filter(key => key.startsWith(prefix))
        .map(key => key.substring(prefix.length))
    } catch (error) {
      console.error('获取存储键名失败:', error)
      return []
    }
  }

  /**
   * 清理过期的存储项
   */
  cleanExpiredSync() {
    try {
      const keys = this.getAllKeysSync()
      let cleanedCount = 0

      keys.forEach(key => {
        const info = this.getInfoSync(key)
        if (info && info.isExpired) {
          this.removeSync(key)
          cleanedCount++
        }
      })

      console.log(`清理了 ${cleanedCount} 个过期存储项`)
      return cleanedCount
    } catch (error) {
      console.error('清理过期存储失败:', error)
      return 0
    }
  }

  /**
   * 获取存储使用情况
   */
  getStorageInfoSync() {
    try {
      const info = uni.getStorageInfoSync()
      const keys = this.getAllKeysSync()
      
      let totalSize = 0
      let expiredCount = 0
      
      keys.forEach(key => {
        const itemInfo = this.getInfoSync(key)
        if (itemInfo) {
          totalSize += itemInfo.size
          if (itemInfo.isExpired) {
            expiredCount++
          }
        }
      })

      return {
        totalKeys: keys.length,
        totalSize,
        expiredCount,
        currentSize: info.currentSize,
        limitSize: info.limitSize,
        usageRate: info.limitSize > 0 ? (info.currentSize / info.limitSize) : 0
      }
    } catch (error) {
      console.error('获取存储信息失败:', error)
      return null
    }
  }

  /**
   * 清空所有存储
   */
  clearAllSync() {
    try {
      const keys = this.getAllKeysSync()
      keys.forEach(key => this.removeSync(key))
      this.cache.clear()
      return true
    } catch (error) {
      console.error('清空存储失败:', error)
      return false
    }
  }

  /**
   * 批量设置存储项
   */
  setBatchSync(items) {
    const results = {}
    
    Object.keys(items).forEach(key => {
      results[key] = this.setSync(key, items[key])
    })
    
    return results
  }

  /**
   * 批量获取存储项
   */
  getBatchSync(keys, defaultValue = null) {
    const results = {}
    
    keys.forEach(key => {
      results[key] = this.getSync(key, defaultValue)
    })
    
    return results
  }

  /**
   * 导出存储数据
   */
  exportSync() {
    try {
      const keys = this.getAllKeysSync()
      const data = {}
      
      keys.forEach(key => {
        const value = this.getSync(key)
        if (value !== null) {
          data[key] = value
        }
      })
      
      return {
        version: '1.0.0',
        timestamp: Date.now(),
        data
      }
    } catch (error) {
      console.error('导出存储数据失败:', error)
      return null
    }
  }

  /**
   * 导入存储数据
   */
  importSync(exportData) {
    try {
      if (!exportData || !exportData.data) {
        throw new Error('无效的导入数据')
      }
      
      const { data } = exportData
      let successCount = 0
      
      Object.keys(data).forEach(key => {
        if (this.setSync(key, data[key])) {
          successCount++
        }
      })
      
      return {
        total: Object.keys(data).length,
        success: successCount,
        failed: Object.keys(data).length - successCount
      }
    } catch (error) {
      console.error('导入存储数据失败:', error)
      return null
    }
  }
}

// 创建默认存储管理器实例
const storage = new StorageManager()

// 便捷方法
export const setStorage = (key, value, options) => storage.set(key, value, options)
export const getStorage = (key, defaultValue) => storage.get(key, defaultValue)
export const removeStorage = (key) => storage.remove(key)
export const hasStorage = (key) => storage.has(key)

export const setStorageSync = (key, value, options) => storage.setSync(key, value, options)
export const getStorageSync = (key, defaultValue) => storage.getSync(key, defaultValue)
export const removeStorageSync = (key) => storage.removeSync(key)
export const hasStorageSync = (key) => storage.hasSync(key)

// 特定业务的存储方法
export const userStorage = {
  setToken: (token) => setStorageSync(STORAGE_KEYS.USER_TOKEN, token),
  getToken: () => getStorageSync(STORAGE_KEYS.USER_TOKEN),
  removeToken: () => removeStorageSync(STORAGE_KEYS.USER_TOKEN),
  
  setUserInfo: (userInfo) => setStorageSync(STORAGE_KEYS.USER_INFO, userInfo),
  getUserInfo: () => getStorageSync(STORAGE_KEYS.USER_INFO),
  removeUserInfo: () => removeStorageSync(STORAGE_KEYS.USER_INFO),
  
  setSettings: (settings) => setStorageSync(STORAGE_KEYS.USER_SETTINGS, settings),
  getSettings: () => getStorageSync(STORAGE_KEYS.USER_SETTINGS, {}),
  
  clear: () => {
    removeStorageSync(STORAGE_KEYS.USER_TOKEN)
    removeStorageSync(STORAGE_KEYS.USER_INFO)
    removeStorageSync(STORAGE_KEYS.USER_SETTINGS)
  }
}

export const appStorage = {
  setConfig: (config) => setStorageSync(STORAGE_KEYS.APP_CONFIG, config),
  getConfig: () => getStorageSync(STORAGE_KEYS.APP_CONFIG, {}),
  
  setLanguage: (language) => setStorageSync(STORAGE_KEYS.LANGUAGE, language),
  getLanguage: () => getStorageSync(STORAGE_KEYS.LANGUAGE, 'zh-CN'),
  
  setTheme: (theme) => setStorageSync(STORAGE_KEYS.THEME, theme),
  getTheme: () => getStorageSync(STORAGE_KEYS.THEME, 'light')
}

export const cacheStorage = {
  setApiCache: (key, data, expireTime = 5 * 60 * 1000) => {
    const cacheData = getStorageSync(STORAGE_KEYS.API_CACHE, {})
    cacheData[key] = {
      data,
      timestamp: Date.now(),
      expireTime
    }
    setStorageSync(STORAGE_KEYS.API_CACHE, cacheData)
  },
  
  getApiCache: (key) => {
    const cacheData = getStorageSync(STORAGE_KEYS.API_CACHE, {})
    const item = cacheData[key]
    
    if (!item) return null
    
    if (Date.now() > item.timestamp + item.expireTime) {
      delete cacheData[key]
      setStorageSync(STORAGE_KEYS.API_CACHE, cacheData)
      return null
    }
    
    return item.data
  },
  
  clearApiCache: () => removeStorageSync(STORAGE_KEYS.API_CACHE)
}

// 导出存储管理器类和实例
export { StorageManager, StorageItem }
export default storage