/**
 * 限流状态自动清理服务
 * 定期检查并清理所有类型账号的过期限流状态
 */

const logger = require('../utils/logger')
const openaiAccountService = require('./openaiAccountService')
const claudeAccountService = require('./claudeAccountService')
const claudeConsoleAccountService = require('./claudeConsoleAccountService')
const unifiedOpenAIScheduler = require('./unifiedOpenAIScheduler')
const webhookService = require('./webhookService')

class RateLimitCleanupService {
  constructor() {
    this.cleanupInterval = null
    this.isRunning = false
    // 默认每5分钟检查一次
    this.intervalMs = 5 * 60 * 1000
    // 存储已清理的账户信息，用于发送恢复通知
    this.clearedAccounts = []
  }

  /**
   * 启动自动清理服务
   * @param {number} intervalMinutes - 检查间隔（分钟），默认5分钟
   */
  start(intervalMinutes = 5) {
    if (this.cleanupInterval) {
      logger.warn('⚠️ Rate limit cleanup service is already running')
      return
    }

    this.intervalMs = intervalMinutes * 60 * 1000

    logger.info(`🧹 Starting rate limit cleanup service (interval: ${intervalMinutes} minutes)`)

    // 立即执行一次清理
    this.performCleanup()

    // 设置定期执行
    this.cleanupInterval = setInterval(() => {
      this.performCleanup()
    }, this.intervalMs)
  }

  /**
   * 停止自动清理服务
   */
  stop() {
    if (this.cleanupInterval) {
      clearInterval(this.cleanupInterval)
      this.cleanupInterval = null
      logger.info('🛑 Rate limit cleanup service stopped')
    }
  }

  /**
   * 执行一次清理检查
   */
  async performCleanup() {
    if (this.isRunning) {
      logger.debug('⏭️ Cleanup already in progress, skipping this cycle')
      return
    }

    this.isRunning = true
    const startTime = Date.now()

    try {
      logger.debug('🔍 Starting rate limit cleanup check...')

      const results = {
        openai: { checked: 0, cleared: 0, errors: [] },
        claude: { checked: 0, cleared: 0, errors: [] },
        claudeConsole: { checked: 0, cleared: 0, errors: [] }
      }

      // 清理 OpenAI 账号
      await this.cleanupOpenAIAccounts(results.openai)

      // 清理 Claude 账号
      await this.cleanupClaudeAccounts(results.claude)

      // 清理 Claude Console 账号
      await this.cleanupClaudeConsoleAccounts(results.claudeConsole)

      const totalChecked =
        results.openai.checked + results.claude.checked + results.claudeConsole.checked
      const totalCleared =
        results.openai.cleared + results.claude.cleared + results.claudeConsole.cleared
      const duration = Date.now() - startTime

      if (totalCleared > 0) {
        logger.info(
          `✅ Rate limit cleanup completed: ${totalCleared} accounts cleared out of ${totalChecked} checked (${duration}ms)`
        )
        logger.info(`   OpenAI: ${results.openai.cleared}/${results.openai.checked}`)
        logger.info(`   Claude: ${results.claude.cleared}/${results.claude.checked}`)
        logger.info(
          `   Claude Console: ${results.claudeConsole.cleared}/${results.claudeConsole.checked}`
        )

        // 发送 webhook 恢复通知
        if (this.clearedAccounts.length > 0) {
          await this.sendRecoveryNotifications()
        }
      } else {
        logger.debug(
          `🔍 Rate limit cleanup check completed: no expired limits found (${duration}ms)`
        )
      }

      // 记录错误
      const allErrors = [
        ...results.openai.errors,
        ...results.claude.errors,
        ...results.claudeConsole.errors
      ]
      if (allErrors.length > 0) {
        logger.warn(`⚠️ Encountered ${allErrors.length} errors during cleanup:`, allErrors)
      }
    } catch (error) {
      logger.error('❌ Rate limit cleanup failed:', error)
    } finally {
      // 确保无论成功或失败都重置列表，避免重复通知
      this.clearedAccounts = []
      this.isRunning = false
    }
  }

  /**
   * 清理 OpenAI 账号的过期限流
   */
  async cleanupOpenAIAccounts(result) {
    try {
      // 使用服务层获取账户数据
      const accounts = await openaiAccountService.getAllAccounts()

      for (const account of accounts) {
        const { rateLimitStatus } = account
        const isRateLimited =
          rateLimitStatus === 'limited' ||
          (rateLimitStatus &&
            typeof rateLimitStatus === 'object' &&
            (rateLimitStatus.status === 'limited' || rateLimitStatus.isRateLimited === true))

        if (isRateLimited) {
          result.checked++

          try {
            // 使用 unifiedOpenAIScheduler 的检查方法，它会自动清除过期的限流
            const isStillLimited = await unifiedOpenAIScheduler.isAccountRateLimited(account.id)

            if (!isStillLimited) {
              result.cleared++
              logger.info(
                `🧹 Auto-cleared expired rate limit for OpenAI account: ${account.name} (${account.id})`
              )

              // 记录已清理的账户信息
              this.clearedAccounts.push({
                platform: 'OpenAI',
                accountId: account.id,
                accountName: account.name,
                previousStatus: 'rate_limited',
                currentStatus: 'active'
              })
            }
          } catch (error) {
            result.errors.push({
              accountId: account.id,
              accountName: account.name,
              error: error.message
            })
          }
        }
      }
    } catch (error) {
      logger.error('Failed to cleanup OpenAI accounts:', error)
      result.errors.push({ error: error.message })
    }
  }

  /**
   * 清理 Claude 账号的过期限流
   */
  async cleanupClaudeAccounts(result) {
    try {
      // 使用 Redis 获取账户数据
      const redis = require('../models/redis')
      const accounts = await redis.getAllClaudeAccounts()

      for (const account of accounts) {
        // 检查是否处于限流状态（兼容对象和字符串格式）
        const isRateLimited =
          account.rateLimitStatus === 'limited' ||
          (account.rateLimitStatus &&
            typeof account.rateLimitStatus === 'object' &&
            account.rateLimitStatus.status === 'limited')

        const autoStopped = account.rateLimitAutoStopped === 'true'
        const needsAutoStopRecovery =
          autoStopped && (account.rateLimitEndAt || account.schedulable === 'false')

        // 检查所有可能处于限流状态的账号，包括自动停止的账号
        if (isRateLimited || account.rateLimitedAt || needsAutoStopRecovery) {
          result.checked++

          try {
            // 使用 claudeAccountService 的检查方法，它会自动清除过期的限流
            const isStillLimited = await claudeAccountService.isAccountRateLimited(account.id)

            if (!isStillLimited) {
              if (!isRateLimited && autoStopped) {
                await claudeAccountService.removeAccountRateLimit(account.id)
              }
              result.cleared++
              logger.info(
                `🧹 Auto-cleared expired rate limit for Claude account: ${account.name} (${account.id})`
              )

              // 记录已清理的账户信息
              this.clearedAccounts.push({
                platform: 'Claude',
                accountId: account.id,
                accountName: account.name,
                previousStatus: 'rate_limited',
                currentStatus: 'active'
              })
            }
          } catch (error) {
            result.errors.push({
              accountId: account.id,
              accountName: account.name,
              error: error.message
            })
          }
        }
      }

      // 检查并恢复因5小时限制被自动停止的账号
      try {
        const fiveHourResult = await claudeAccountService.checkAndRecoverFiveHourStoppedAccounts()

        if (fiveHourResult.recovered > 0) {
          // 将5小时限制恢复的账号也加入到已清理账户列表中，用于发送通知
          for (const account of fiveHourResult.accounts) {
            this.clearedAccounts.push({
              platform: 'Claude',
              accountId: account.id,
              accountName: account.name,
              previousStatus: '5hour_limited',
              currentStatus: 'active',
              windowInfo: account.newWindow
            })
          }

          // 更新统计数据
          result.checked += fiveHourResult.checked
          result.cleared += fiveHourResult.recovered

          logger.info(
            `🕐 Claude 5-hour limit recovery: ${fiveHourResult.recovered}/${fiveHourResult.checked} accounts recovered`
          )
        }
      } catch (error) {
        logger.error('Failed to check and recover 5-hour stopped Claude accounts:', error)
        result.errors.push({
          type: '5hour_recovery',
          error: error.message
        })
      }
    } catch (error) {
      logger.error('Failed to cleanup Claude accounts:', error)
      result.errors.push({ error: error.message })
    }
  }

  /**
   * 清理 Claude Console 账号的过期限流
   */
  async cleanupClaudeConsoleAccounts(result) {
    try {
      // 使用服务层获取账户数据
      const accounts = await claudeConsoleAccountService.getAllAccounts()

      for (const account of accounts) {
        // 检查是否处于限流状态（兼容对象和字符串格式）
        const isRateLimited =
          account.rateLimitStatus === 'limited' ||
          (account.rateLimitStatus &&
            typeof account.rateLimitStatus === 'object' &&
            account.rateLimitStatus.status === 'limited')

        const autoStopped = account.rateLimitAutoStopped === 'true'
        const needsAutoStopRecovery = autoStopped && account.schedulable === 'false'

        // 检查两种状态字段：rateLimitStatus 和 status
        const hasStatusRateLimited = account.status === 'rate_limited'

        if (isRateLimited || hasStatusRateLimited || needsAutoStopRecovery) {
          result.checked++

          try {
            // 使用 claudeConsoleAccountService 的检查方法，它会自动清除过期的限流
            const isStillLimited = await claudeConsoleAccountService.isAccountRateLimited(
              account.id
            )

            if (!isStillLimited) {
              if (!isRateLimited && autoStopped) {
                await claudeConsoleAccountService.removeAccountRateLimit(account.id)
              }
              result.cleared++

              // 如果 status 字段是 rate_limited，需要额外清理
              if (hasStatusRateLimited && !isRateLimited) {
                await claudeConsoleAccountService.updateAccount(account.id, {
                  status: 'active'
                })
              }

              logger.info(
                `🧹 Auto-cleared expired rate limit for Claude Console account: ${account.name} (${account.id})`
              )

              // 记录已清理的账户信息
              this.clearedAccounts.push({
                platform: 'Claude Console',
                accountId: account.id,
                accountName: account.name,
                previousStatus: 'rate_limited',
                currentStatus: 'active'
              })
            }
          } catch (error) {
            result.errors.push({
              accountId: account.id,
              accountName: account.name,
              error: error.message
            })
          }
        }
      }
    } catch (error) {
      logger.error('Failed to cleanup Claude Console accounts:', error)
      result.errors.push({ error: error.message })
    }
  }

  /**
   * 手动触发一次清理（供 API 或 CLI 调用）
   */
  async manualCleanup() {
    logger.info('🧹 Manual rate limit cleanup triggered')
    await this.performCleanup()
  }

  /**
   * 发送限流恢复通知
   */
  async sendRecoveryNotifications() {
    try {
      // 按平台分组账户
      const groupedAccounts = {}
      for (const account of this.clearedAccounts) {
        if (!groupedAccounts[account.platform]) {
          groupedAccounts[account.platform] = []
        }
        groupedAccounts[account.platform].push(account)
      }

      // 构建通知消息
      const platforms = Object.keys(groupedAccounts)
      const totalAccounts = this.clearedAccounts.length

      let message = `🎉 共有 ${totalAccounts} 个账户的限流状态已恢复\n\n`

      for (const platform of platforms) {
        const accounts = groupedAccounts[platform]
        message += `**${platform}** (${accounts.length} 个):\n`
        for (const account of accounts) {
          message += `• ${account.accountName} (ID: ${account.accountId})\n`
        }
        message += '\n'
      }

      // 发送 webhook 通知
      await webhookService.sendNotification('rateLimitRecovery', {
        title: '限流恢复通知',
        message,
        totalAccounts,
        platforms: Object.keys(groupedAccounts),
        accounts: this.clearedAccounts,
        timestamp: new Date().toISOString()
      })

      logger.info(`📢 已发送限流恢复通知，涉及 ${totalAccounts} 个账户`)
    } catch (error) {
      logger.error('❌ 发送限流恢复通知失败:', error)
    }
  }

  /**
   * 获取服务状态
   */
  getStatus() {
    return {
      running: !!this.cleanupInterval,
      intervalMinutes: this.intervalMs / (60 * 1000),
      isProcessing: this.isRunning
    }
  }
}

// 创建单例实例
const rateLimitCleanupService = new RateLimitCleanupService()

module.exports = rateLimitCleanupService
