import storage from './storage'
import http from './http'
import device from './device'
import { STORAGE_KEYS, DEFAULT_CONFIG } from './constants'

/**
 * 事件队列管理
 * 支持批量上报、离线缓存、失败重试
 */
class EventQueue {
  constructor() {
    this.queue = []
    this.maxSize = DEFAULT_CONFIG.queue.maxSize
    this.flushInterval = DEFAULT_CONFIG.queue.flushInterval
    this.maxOfflineEvents = DEFAULT_CONFIG.offline.maxEvents
    this.flushTimer = null
    this.isFlushing = false
    this.debug = false
    this.immediateEvents = []
  }

  /**
   * 初始化配置
   */
  init(config = {}) {
    this.maxSize = config.queue?.maxSize || this.maxSize
    this.flushInterval = config.queue?.flushInterval || this.flushInterval
    this.maxOfflineEvents = config.offline?.maxEvents || this.maxOfflineEvents
    this.debug = config.debug || false
    this.immediateEvents = config.immediateEvents || []

    // 加载离线缓存的事件
    this._loadOfflineEvents()

    // 启动定时上报
    this._startFlushTimer()

    // 监听网络变化，联网时尝试上报
    this._watchNetworkChange()
  }

  /**
   * 加载离线缓存的事件
   */
  _loadOfflineEvents() {
    const offlineEvents = storage.getJSON(STORAGE_KEYS.OFFLINE_EVENTS, [])
    if (offlineEvents.length > 0) {
      this._log(`Loaded ${offlineEvents.length} offline events`)
      this.queue = [...offlineEvents, ...this.queue]
      // 清除存储
      storage.remove(STORAGE_KEYS.OFFLINE_EVENTS)
    }
  }

  /**
   * 保存事件到离线缓存
   */
  _saveOfflineEvents(events) {
    const existingEvents = storage.getJSON(STORAGE_KEYS.OFFLINE_EVENTS, [])
    const allEvents = [...existingEvents, ...events]

    // 限制离线缓存数量
    const trimmedEvents = allEvents.slice(-this.maxOfflineEvents)
    storage.setJSON(STORAGE_KEYS.OFFLINE_EVENTS, trimmedEvents)

    this._log(`Saved ${events.length} events to offline cache`)
  }

  /**
   * 启动定时上报
   */
  _startFlushTimer() {
    if (this.flushTimer) {
      clearInterval(this.flushTimer)
    }

    this.flushTimer = setInterval(() => {
      this.flush()
    }, this.flushInterval)
  }

  /**
   * 停止定时上报
   */
  _stopFlushTimer() {
    if (this.flushTimer) {
      clearInterval(this.flushTimer)
      this.flushTimer = null
    }
  }

  /**
   * 监听网络变化
   */
  _watchNetworkChange() {
    device.onNetworkChange((res) => {
      if (res.isConnected) {
        this._log('Network connected, attempting to flush')
        this.flush()
      }
    })
  }

  /**
   * 添加事件到队列
   */
  add(event) {
    // 检查是否为需要立即上报的事件
    if (this.immediateEvents.includes(event.event)) {
      this._log(`Immediate event: ${event.event}`)
      this._sendImmediately(event)
      return
    }

    this.queue.push(event)
    this._log(`Event added to queue: ${event.event} (queue size: ${this.queue.length})`)

    // 检查是否达到上报阈值
    if (this.queue.length >= this.maxSize) {
      this.flush()
    }
  }

  /**
   * 立即发送单个事件
   */
  async _sendImmediately(event) {
    if (!device.isOnline()) {
      this._saveOfflineEvents([event])
      return
    }

    try {
      await http.capture(event.event, event.distinct_id, event.properties, event.timestamp)
      this._log(`Immediate event sent: ${event.event}`)
    } catch (error) {
      this._log(`Immediate event failed: ${event.event}`, error)
      this._saveOfflineEvents([event])
    }
  }

  /**
   * 刷新队列，批量上报
   */
  async flush() {
    // 防止并发刷新
    if (this.isFlushing || this.queue.length === 0) {
      return
    }

    // 检查网络状态
    if (!device.isOnline()) {
      this._log('Offline, saving events to cache')
      this._saveOfflineEvents([...this.queue])
      this.queue = []
      return
    }

    this.isFlushing = true
    const eventsToSend = [...this.queue]
    this.queue = []

    this._log(`Flushing ${eventsToSend.length} events`)

    try {
      await http.batch(eventsToSend)
      this._log(`Successfully sent ${eventsToSend.length} events`)
    } catch (error) {
      this._log('Batch send failed, saving to offline cache', error)
      this._saveOfflineEvents(eventsToSend)
    } finally {
      this.isFlushing = false
    }
  }

  /**
   * 强制刷新（应用退出时调用）
   */
  async forceFlush() {
    this._stopFlushTimer()
    await this.flush()
  }

  /**
   * 获取队列长度
   */
  getQueueSize() {
    return this.queue.length
  }

  /**
   * 清空队列
   */
  clear() {
    this.queue = []
    storage.remove(STORAGE_KEYS.OFFLINE_EVENTS)
  }

  /**
   * 调试日志
   */
  _log(...args) {
    if (this.debug) {
      console.log('[PostHog Queue]', ...args)
    }
  }

  /**
   * 销毁队列
   */
  destroy() {
    this._stopFlushTimer()
    this.forceFlush()
  }
}

// 导出单例
export default new EventQueue()