// src/utils/versionChecker.js
// 版本检查工具

import { imageCacheManager } from '@/utils/image/imageCacheManager'

const PERSISTENT_KEYS = [
  'preferred-language', // 语言设置
  'userProfile', // 用户资料
  'teamInfo', // 团队信息
  'lastImgUrl', // 最后图片URL
  'applyInfo', // 申请资料
  'gamesKing', // 游戏王每日弹窗查看状态
]

export class VersionChecker {
  constructor() {
    this.currentVersion = import.meta.env.VITE_APP_VERSION || Date.now().toString() //app版本号
    this.storageKey = 'h5_app_version' //本地存储的版本号key
    this.serverVersionKey = 'app_server_version' //服务器版本号key
    this.enableCheck = import.meta.env.VITE_ENABLE_VERSION_CHECK === 'true' //是否开启检测app版本号
  }

  // 检查版本（开发环境：本地.env文件；生产环境：构建脚本生成的version.json文件）
  async checkServerVersion() {
    if (!this.enableCheck) {
      return false
    }

    try {
      let versionInfo //版本更新信息

      // 开发环境：使用本地.env文件环境变量
      if (import.meta.env.MODE === 'development') {
        versionInfo = {
          version: import.meta.env.VITE_APP_VERSION,
          type: import.meta.env.VITE_VERSION_TYPE || 'patch',
        }
      }
      // 生产环境：从服务器获取version.json文件
      else {
        const response = await fetch(`/version.json?t=${Date.now()}`)
        if (!response.ok) {
          console.warn('无法获取服务器版本信息')
          return false
        }

        const contentType = response.headers.get('content-type')
        if (!contentType || !contentType.includes('application/json')) {
          console.warn('服务器返回的不是JSON格式')
          return false
        }

        versionInfo = await response.json() //获取服务器版本信息
      }

      const serverVersion = versionInfo.version //最新生成的服务器版本号
      const versionType = versionInfo.type || 'patch' // 版本更新类型
      const storedServerVersion = localStorage.getItem(this.serverVersionKey) //网页缓存的版本号

      // 更新服务器版本信息
      localStorage.setItem(this.serverVersionKey, serverVersion)

      // 比较版本
      if (storedServerVersion && storedServerVersion !== serverVersion) {
        console.log(`检测到${versionType}版本更新: ${storedServerVersion} -> ${serverVersion}`)

        // 返回版本类型信息
        return {
          shouldUpdate: true,
          versionType: versionType,
        }
      }

      return { shouldUpdate: false }
    } catch (error) {
      console.warn('版本检查失败:', error.message)
      return { shouldUpdate: false }
    }
  }

  // 初始化网页首次检查版本
  async checkVersion() {
    // 获取最新版本信息
    const versionResult = await this.checkServerVersion()

    // 判断是否需要更新
    if (versionResult.shouldUpdate) {
      await this.handleVersionUpdate(versionResult.versionType)
      return true
    }

    // 检查本地版本是否匹配
    const storedLocalVersion = localStorage.getItem(this.storageKey)

    if (storedLocalVersion !== this.currentVersion) {
      // 本地版本变化，可能是首次加载或本地版本升级
      localStorage.setItem(this.storageKey, this.currentVersion)
      console.log(`本地版本更新到: ${this.currentVersion}`)
    }

    return false
  }

  // 处理版本更新
  async handleVersionUpdate(updateType = 'major') {
    console.log(`检测到${updateType}版本更新，正在清理缓存...`)

    // 根据更新类型决定清除策略
    switch (updateType) {
      case 'major':
        // 重大更新：清除所有缓存（不管图片版本号是否更新）
        await this.clearCache()
        break
      case 'minor':
      case 'patch':
        // minor或patch更新：检查图片版本号是否更新
        // 如果图片版本号更新，则按imageCacheVersion中的cacheType清除缓存
        // 如果图片版本号未更新，则不做任何缓存清除处理
        await imageCacheManager.checkVersionAndUpdate()
        this.clearSessionData() // 清除 session 数据
        break
      default:
        // 默认：清除所有缓存
        await this.clearCache()
    }

    localStorage.setItem(this.storageKey, this.currentVersion)
    localStorage.setItem(this.serverVersionKey, this.currentVersion)

    // 直接刷新页面
    this.forceReload()
  }

  // 清除所有会话存储数据sessionStorage
  clearSessionData() {
    try {
      // localStorage和Cache API不受影响
      const preservedData = {}
      PERSISTENT_KEYS.forEach((key) => {
        const value = localStorage.getItem(key)
        if (value !== null) {
          preservedData[key] = value
        }
      })

      // 清除 sessionStorage
      sessionStorage.clear()

      // 恢复保留的数据
      Object.keys(preservedData).forEach((key) => {
        localStorage.setItem(key, preservedData[key])
      })
    } catch (error) {
      console.warn('清理 session 数据失败:', error)
    }
  }

  async clearCache() {
    // 清除范围：
    // localStorage：所有本地存储数据
    // sessionStorage：所有会话存储数据
    // Cache API：所有缓存（包括非图片缓存）
    // Service Worker：注销所有注册
    // 保留数据：保留 PERSISTENT_KEYS 中定义的白名单数据

    try {
      // 保存需要保留的数据
      const preservedData = {}
      PERSISTENT_KEYS.forEach((key) => {
        const value = localStorage.getItem(key)
        if (value !== null) {
          preservedData[key] = value
        }
      })

      // 清除所有localStorage
      localStorage.clear()

      // 恢复保留的数据
      Object.keys(preservedData).forEach((key) => {
        localStorage.setItem(key, preservedData[key])
      })

      // 清除sessionStorage
      sessionStorage.clear()

      // 清除所有缓存
      if ('caches' in window) {
        const cacheNames = await caches.keys()
        await Promise.all(cacheNames.map((name) => caches.delete(name)))
      }

      // 注销Service Worker（如果存在）
      if ('serviceWorker' in navigator) {
        const registrations = await navigator.serviceWorker.getRegistrations()
        await Promise.all(registrations.map((reg) => reg.unregister()))
      }
    } catch (error) {
      console.warn('清除缓存失败:', error)
    }
  }

  // 强制刷新页面
  forceReload() {
    // 直接刷新当前页面，不跳转到其他页面
    try {
      window.location.reload(true)
    } catch (error) {
      // 备用方案
      window.location.href = window.location.href
    }
  }

  // 获取当前版本
  getCurrentVersion() {
    return this.currentVersion
  }
}

// 导出单例
export const versionChecker = new VersionChecker()
