const redis = require('../models/redis')
const apiKeyService = require('./apiKeyService')
const CostCalculator = require('../utils/costCalculator')
const logger = require('../utils/logger')

class CostInitService {
  /**
   * 初始化所有API Key的费用数据
   * 扫描历史使用记录并计算费用
   */
  async initializeAllCosts() {
    try {
      logger.info('💰 Starting cost initialization for all API Keys...')

      const apiKeys = await apiKeyService.getAllApiKeys()
      const client = redis.getClientSafe()

      let processedCount = 0
      let errorCount = 0

      for (const apiKey of apiKeys) {
        try {
          await this.initializeApiKeyCosts(apiKey.id, client)
          processedCount++

          if (processedCount % 10 === 0) {
            logger.info(`💰 Processed ${processedCount} API Keys...`)
          }
        } catch (error) {
          errorCount++
          logger.error(`❌ Failed to initialize costs for API Key ${apiKey.id}:`, error)
        }
      }

      logger.success(
        `💰 Cost initialization completed! Processed: ${processedCount}, Errors: ${errorCount}`
      )
      return { processed: processedCount, errors: errorCount }
    } catch (error) {
      logger.error('❌ Failed to initialize costs:', error)
      throw error
    }
  }

  /**
   * 初始化单个API Key的费用数据
   */
  async initializeApiKeyCosts(apiKeyId, client) {
    // 获取所有时间的模型使用统计
    const modelKeys = await client.keys(`usage:${apiKeyId}:model:*:*:*`)

    // 按日期分组统计
    const dailyCosts = new Map() // date -> cost
    const monthlyCosts = new Map() // month -> cost
    const hourlyCosts = new Map() // hour -> cost

    for (const key of modelKeys) {
      // 解析key格式: usage:{keyId}:model:{period}:{model}:{date}
      const match = key.match(
        /usage:(.+):model:(daily|monthly|hourly):(.+):(\d{4}-\d{2}(?:-\d{2})?(?::\d{2})?)$/
      )
      if (!match) {
        continue
      }

      const [, , period, model, dateStr] = match

      // 获取使用数据
      const data = await client.hgetall(key)
      if (!data || Object.keys(data).length === 0) {
        continue
      }

      // 计算费用
      const usage = {
        input_tokens: parseInt(data.totalInputTokens) || parseInt(data.inputTokens) || 0,
        output_tokens: parseInt(data.totalOutputTokens) || parseInt(data.outputTokens) || 0,
        cache_creation_input_tokens:
          parseInt(data.totalCacheCreateTokens) || parseInt(data.cacheCreateTokens) || 0,
        cache_read_input_tokens:
          parseInt(data.totalCacheReadTokens) || parseInt(data.cacheReadTokens) || 0
      }

      const costResult = CostCalculator.calculateCost(usage, model)
      const cost = costResult.costs.total

      // 根据period分组累加费用
      if (period === 'daily') {
        const currentCost = dailyCosts.get(dateStr) || 0
        dailyCosts.set(dateStr, currentCost + cost)
      } else if (period === 'monthly') {
        const currentCost = monthlyCosts.get(dateStr) || 0
        monthlyCosts.set(dateStr, currentCost + cost)
      } else if (period === 'hourly') {
        const currentCost = hourlyCosts.get(dateStr) || 0
        hourlyCosts.set(dateStr, currentCost + cost)
      }
    }

    // 将计算出的费用写入Redis
    const promises = []

    // 写入每日费用
    for (const [date, cost] of dailyCosts) {
      const key = `usage:cost:daily:${apiKeyId}:${date}`
      promises.push(
        client.set(key, cost.toString()),
        client.expire(key, 86400 * 30) // 30天过期
      )
    }

    // 写入每月费用
    for (const [month, cost] of monthlyCosts) {
      const key = `usage:cost:monthly:${apiKeyId}:${month}`
      promises.push(
        client.set(key, cost.toString()),
        client.expire(key, 86400 * 90) // 90天过期
      )
    }

    // 写入每小时费用
    for (const [hour, cost] of hourlyCosts) {
      const key = `usage:cost:hourly:${apiKeyId}:${hour}`
      promises.push(
        client.set(key, cost.toString()),
        client.expire(key, 86400 * 7) // 7天过期
      )
    }

    // 计算总费用
    let totalCost = 0
    for (const cost of dailyCosts.values()) {
      totalCost += cost
    }

    // 写入总费用
    if (totalCost > 0) {
      const totalKey = `usage:cost:total:${apiKeyId}`
      promises.push(client.set(totalKey, totalCost.toString()))
    }

    await Promise.all(promises)

    logger.debug(
      `💰 Initialized costs for API Key ${apiKeyId}: Daily entries: ${dailyCosts.size}, Total cost: $${totalCost.toFixed(2)}`
    )
  }

  /**
   * 检查是否需要初始化费用数据
   */
  async needsInitialization() {
    try {
      const client = redis.getClientSafe()

      // 检查是否有任何费用数据
      const costKeys = await client.keys('usage:cost:*')

      // 如果没有费用数据，需要初始化
      if (costKeys.length === 0) {
        logger.info('💰 No cost data found, initialization needed')
        return true
      }

      // 检查是否有使用数据但没有对应的费用数据
      const sampleKeys = await client.keys('usage:*:model:daily:*:*')
      if (sampleKeys.length > 10) {
        // 抽样检查
        const sampleSize = Math.min(10, sampleKeys.length)
        for (let i = 0; i < sampleSize; i++) {
          const usageKey = sampleKeys[Math.floor(Math.random() * sampleKeys.length)]
          const match = usageKey.match(/usage:(.+):model:daily:(.+):(\d{4}-\d{2}-\d{2})$/)
          if (match) {
            const [, keyId, , date] = match
            const costKey = `usage:cost:daily:${keyId}:${date}`
            const hasCost = await client.exists(costKey)
            if (!hasCost) {
              logger.info(
                `💰 Found usage without cost data for key ${keyId} on ${date}, initialization needed`
              )
              return true
            }
          }
        }
      }

      logger.info('💰 Cost data appears to be up to date')
      return false
    } catch (error) {
      logger.error('❌ Failed to check initialization status:', error)
      return false
    }
  }
}

module.exports = new CostInitService()
