const { getRedisClient } = require("./client")
const { recordCacheMiss } = require("./cacheMetrics.service")

const CATEGORIES_KEY = "data:categories"

function createRedisClient() {
  return getRedisClient()
}

async function getCategoryById(id) {
  const cid = Number(id)
  if (!Number.isInteger(cid) || cid < 0) return null
  const redis = createRedisClient()
  try {
    const raw = await redis.hget(CATEGORIES_KEY, String(cid))
    if (!raw) {
      await recordCacheMiss({ key: `${CATEGORIES_KEY}:${cid}`, label: "category" })
    }
    return raw ? JSON.parse(raw) : null
  } catch {
    return null
  } finally {}
}

async function setCategoryInRedis(category) {
  if (!category?.id) return false
  const redis = createRedisClient()
  try {
    await redis.hset(CATEGORIES_KEY, String(category.id), JSON.stringify(category))
    return true
  } finally {}
}

async function setCategoriesInRedis(categories = []) {
  const list = Array.isArray(categories) ? categories : []
  if (!list.length) return 0
  const redis = createRedisClient()
  try {
    const pipeline = redis.pipeline()
    list.forEach((cat) => {
      if (!cat?.id) return
      pipeline.hset(CATEGORIES_KEY, String(cat.id), JSON.stringify(cat))
    })
    await pipeline.exec()
    return list.length
  } finally {}
}

async function removeCategoryFromRedis(categoryId) {
  const cid = Number(categoryId)
  if (!Number.isInteger(cid) || cid < 0) return 0
  const redis = createRedisClient()
  try {
    await redis.hdel(CATEGORIES_KEY, String(cid))
    return 1
  } finally {}
}

async function listCategoriesFromRedis() {
  const redis = createRedisClient()
  try {
    const raw = await redis.hgetall(CATEGORIES_KEY)
    const list = []
    for (const value of Object.values(raw || {})) {
      try {
        const parsed = JSON.parse(value)
        if (parsed && parsed.id !== undefined) list.push(parsed)
      } catch {
        continue
      }
    }
    return list
  } catch {
    return []
  } finally {}
}

module.exports = {
  CATEGORIES_KEY,
  getCategoryById,
  setCategoryInRedis,
  setCategoriesInRedis,
  removeCategoryFromRedis,
  listCategoriesFromRedis,
}
