const { getRedisClient } = require("./redis/client")
const dealReportDb = require("../db/dealReport.db")
const {
  VOTE_HASH_KEY,
  COMMENT_LIKE_HASH_KEY,
  COMMENT_HASH_KEY,
  COMMENT_DELETE_HASH_KEY,
  DEAL_UPDATE_HASH_KEY,
  DEAL_CREATE_HASH_KEY,
  DEAL_AI_REVIEW_HASH_KEY,
  NOTIFICATION_HASH_KEY,
  NOTIFICATION_READ_HASH_KEY,
  DEAL_SAVE_HASH_KEY,
  AUDIT_HASH_KEY,
  USER_UPDATE_HASH_KEY,
  USER_NOTE_HASH_KEY,
  DEAL_REPORT_UPDATE_HASH_KEY,
  CATEGORY_UPSERT_HASH_KEY,
  SELLER_UPSERT_HASH_KEY,
  SELLER_DOMAIN_UPSERT_HASH_KEY,
} = require("./redis/dbSync.service")

function createRedisClient() {
  return getRedisClient()
}

function parseRedisInfo(raw = "") {
  const info = {}
  String(raw)
    .split("\n")
    .forEach((line) => {
      if (!line || line.startsWith("#")) return
      const idx = line.indexOf(":")
      if (idx <= 0) return
      const key = line.slice(0, idx)
      const value = line.slice(idx + 1).trim()
      info[key] = value
    })
  return info
}

async function getPendingDealCount(redis) {
  try {
    const result = await redis.call(
      "FT.SEARCH",
      "idx:data:deals",
      "@status:{PENDING}",
      "LIMIT",
      0,
      0
    )
    const total = Array.isArray(result) ? Number(result[0]) : null
    return Number.isFinite(total) ? total : 0
  } catch (err) {
    return null
  }
}

async function getQueueSizes(redis) {
  const keys = [
    VOTE_HASH_KEY,
    COMMENT_LIKE_HASH_KEY,
    COMMENT_HASH_KEY,
    COMMENT_DELETE_HASH_KEY,
    DEAL_UPDATE_HASH_KEY,
    DEAL_CREATE_HASH_KEY,
    DEAL_AI_REVIEW_HASH_KEY,
    NOTIFICATION_HASH_KEY,
    NOTIFICATION_READ_HASH_KEY,
    DEAL_SAVE_HASH_KEY,
    AUDIT_HASH_KEY,
    USER_UPDATE_HASH_KEY,
    USER_NOTE_HASH_KEY,
    DEAL_REPORT_UPDATE_HASH_KEY,
    CATEGORY_UPSERT_HASH_KEY,
    SELLER_UPSERT_HASH_KEY,
    SELLER_DOMAIN_UPSERT_HASH_KEY,
  ]

  const pipeline = redis.pipeline()
  keys.forEach((key) => pipeline.hlen(key))
  const results = await pipeline.exec()

  const sizes = {}
  keys.forEach((key, idx) => {
    const value = results?.[idx]?.[1]
    sizes[key] = Number.isFinite(Number(value)) ? Number(value) : 0
  })
  return sizes
}

async function getAdminMetrics() {
  const redis = createRedisClient()
  try {
    const [pendingDeals, queues, infoRaw, openReports] = await Promise.all([
      getPendingDealCount(redis),
      getQueueSizes(redis),
      redis.info(),
      dealReportDb.countDealReports({ status: "OPEN" }),
    ])
    const info = parseRedisInfo(infoRaw)

    return {
      pendingDeals,
      openReports,
      redis: {
        usedMemory: info.used_memory ?? null,
        connectedClients: info.connected_clients ?? null,
        keyspaceHits: info.keyspace_hits ?? null,
        keyspaceMisses: info.keyspace_misses ?? null,
      },
      dbsyncQueues: queues,
    }
  } finally {}
}

module.exports = { getAdminMetrics }
