import { getToken } from '@/utils/auth'

/**
 * 服务器存储策略
 * 支持离线队列，网络恢复后自动重传
 */
class ServerStorage {
  constructor(key, options = {}) {
    this.key = key
    this.options = {
      endpoint: options.endpoint || '/system/business/test/testLblh',
      syncEndpoint:
        options.syncEndpoint || '/system/business/test/testLblhHistory',
      historyEndpoint:
        options.historyEndpoint || '/system/business/test/testLblhHistory',
      retryCount: options.retryCount || 3, //最多重试次数
      retryDelay: options.retryDelay || 1000, //重试等待 毫秒
      ...options
    }

    this.queue = []
    this.isOnline = navigator.onLine
    this.isSyncing = false
    this.initOfflineQueue()
    this.setupNetworkListeners()
  }

  /**
   * 初始化离线队列
   */
  initOfflineQueue() {
    const queueStr = localStorage.getItem(`hxhq_serverQueue_${this.key}`)
    if (queueStr) {
      try {
        this.queue = JSON.parse(queueStr)
      } catch (error) {
        this.queue = []
      }
    }
  }

  /**
   * 设置网络状态监听
   */
  setupNetworkListeners() {
    window.addEventListener('online', () => {
      this.isOnline = true
      this.processQueue()
    })

    window.addEventListener('offline', () => {
      this.isOnline = false
    })
  }

  /**
   * 保存队列到本地存储
   */
  saveQueue() {
    localStorage.setItem(
      `hxhq_serverQueue_${this.key}`,
      JSON.stringify(this.queue)
    )
  }

  /**
   * 处理离线队列
   */
  async processQueue() {
    if (this.isSyncing || !this.isOnline || this.queue.length === 0) {
      return
    }

    this.isSyncing = true

    while (this.queue.length > 0 && this.isOnline) {
      const item = this.queue[0]
      try {
        await this.sendToServer(item.content, item.timestamp, item.version)
        this.queue.shift() // 发送成功，从队列移除
        this.saveQueue()
      } catch (error) {
        console.error('同步失败:', error)
        item.retryCount = (item.retryCount || 0) + 1

        if (item.retryCount >= this.options.retryCount) {
          this.queue.shift() // 超过重试次数，移除
          this.saveQueue()
        } else {
          // 重试等待
          await new Promise((resolve) =>
            setTimeout(resolve, this.options.retryDelay * item.retryCount)
          )
        }
      }
    }

    this.isSyncing = false
  }

  /**
   * 发送数据到服务器
   * @param {string} content - 内容
   * @param {number} timestamp - 时间戳
   * @param {number} version - 版本号
   */
  async sendToServer(content, timestamp, version) {
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest()
      xhr.open('POST', this.options.endpoint)
      xhr.setRequestHeader('Content-Type', 'application/json')
      xhr.setRequestHeader('Authorization', 'Bearer ' + getToken()) // 让每个请求携带自定义token 请根据实际情况自行修改

      xhr.onload = () => {
        if (xhr.status === 200 || xhr.status === 201) {
          resolve(JSON.parse(xhr.responseText))
        } else {
          reject(new Error(`服务器错误: ${xhr.status}`))
        }
      }

      xhr.onerror = () => reject(new Error('网络请求失败'))
      xhr.ontimeout = () => reject(new Error('请求超时'))

      xhr.send(
        JSON.stringify({
          key: this.key,
          content,
          timestamp,
          version,
          syncedAt: Date.now()
        })
      )
    })
  }

  /**
   * 保存数据（优先尝试服务器，失败则加入离线队列）
   * @param {string} content - 要保存的内容
   * @returns {Promise<object>} 保存结果
   */
  async save(content) {
    try {
      const timestamp = Date.now()
      const version = await this.getNextVersion()

      if (this.isOnline) {
        try {
          const result = await this.sendToServer(content, timestamp, version)
          return {
            success: true,
            timestamp,
            version,
            storage: 'server',
            synced: true
          }
        } catch (error) {
          // 服务器保存失败，加入离线队列
          console.warn('服务器保存失败，加入离线队列:', error)
        }
      }

      // 离线或服务器失败，加入队列
      this.queue.push({
        content,
        timestamp,
        version,
        addedAt: Date.now()
      })
      this.saveQueue()

      return {
        success: true,
        timestamp,
        version,
        storage: 'server',
        synced: false,
        queued: true
      }
    } catch (error) {
      return {
        success: false,
        error: error.message,
        storage: 'server'
      }
    }
  }

  /**
   * 从服务器加载数据（失败则返回离线数据）
   * @returns {Promise<object>} 加载的数据
   */
  async load() {
    try {
      // if (this.isOnline) {
      //   try {
      //     const response = await fetch(`${this.options.syncEndpoint}?key=${this.key}`);
      //     if (response.ok) {
      //       const data = await response.json();
      //       return {
      //         success: true,
      //         data,
      //         storage: 'server',
      //         fromServer: true
      //       };
      //     }
      //   } catch (error) {
      //     console.warn('从服务器加载失败:', error);
      //   }
      // }

      // 返回队列中的最新数据
      const latestQueued =
        this.queue.length > 0 ? this.queue[this.queue.length - 1] : null

      return {
        success: true,
        data: latestQueued,
        storage: 'server',
        fromServer: false
      }
    } catch (error) {
      return {
        success: false,
        error: error.message,
        storage: 'server'
      }
    }
  }

  /**
   * 获取服务器历史版本
   * @returns {Promise<Array>} 历史版本列表
   */
  async getHistory() {
    try {
      if (!this.isOnline) {
        return {
          success: false,
          error: '网络未连接',
          storage: 'server'
        }
      }

      const response = await fetch(
        `${this.options.historyEndpoint}?key=${this.key}`
      )
      if (!response.ok) {
        throw new Error(`服务器错误: ${response.status}`)
      }

      const data = await response.json()
      return {
        success: true,
        data,
        storage: 'server'
      }
    } catch (error) {
      return {
        success: false,
        error: error.message,
        storage: 'server'
      }
    }
  }

  /**
   * 获取下一个版本号
   * @returns {Promise<number>} 版本号
   */
  async getNextVersion() {
    try {
      const result = await this.load()
      if (result.success && result.data) {
        return result.data.version + 1
      }
      return 1
    } catch (error) {
      return 1
    }
  }

  /**
   * 获取队列状态
   * @returns {object} 队列状态
   */
  getQueueStatus() {
    return {
      queuedCount: this.queue.length,
      isOnline: this.isOnline,
      isSyncing: this.isSyncing,
      nextRetry: this.queue.length > 0 ? this.queue[0].retryCount || 0 : 0
    }
  }
}

export default ServerStorage
