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

const USER_MOD_KEY_PREFIX = "users:moderation:"
const DEFAULT_TTL_SECONDS = 60 * 60

function createRedisClient() {
  return getRedisClient()
}

function normalizeUserId(userId) {
  const id = Number(userId)
  return Number.isInteger(id) && id > 0 ? id : null
}

function normalizeModerationPayload(user) {
  const id = normalizeUserId(user?.id)
  if (!id) return null
  return {
    id,
    role: user?.role ?? "USER",
    mutedUntil: user?.mutedUntil ? new Date(user.mutedUntil).toISOString() : null,
    suspendedUntil: user?.suspendedUntil ? new Date(user.suspendedUntil).toISOString() : null,
    disabledAt: user?.disabledAt ? new Date(user.disabledAt).toISOString() : null,
  }
}

async function getUserModerationFromRedis(userId) {
  const id = normalizeUserId(userId)
  if (!id) return null
  const redis = createRedisClient()
  try {
    const raw = await redis.call("JSON.GET", `${USER_MOD_KEY_PREFIX}${id}`)
    if (!raw) {
      await recordCacheMiss({ key: `${USER_MOD_KEY_PREFIX}${id}`, label: "user-mod" })
    }
    return raw ? JSON.parse(raw) : null
  } catch {
    return null
  } finally {}
}

async function setUserModerationInRedis(user, { ttlSeconds = DEFAULT_TTL_SECONDS } = {}) {
  const payload = normalizeModerationPayload(user)
  if (!payload) return false
  const redis = createRedisClient()
  const key = `${USER_MOD_KEY_PREFIX}${payload.id}`
  try {
    await redis.call("JSON.SET", key, "$", JSON.stringify(payload))
    if (ttlSeconds) await redis.expire(key, Number(ttlSeconds))
    return true
  } catch {
    return false
  } finally {}
}

async function getOrCacheUserModeration(userId) {
  const id = normalizeUserId(userId)
  if (!id) return null
  const cached = await getUserModerationFromRedis(id)
  if (cached) return cached

  const user = await userDb.findUser(
    { id },
    { select: { id: true, role: true, mutedUntil: true, suspendedUntil: true, disabledAt: true } }
  )
  if (!user) return null
  await setUserModerationInRedis(user, { ttlSeconds: DEFAULT_TTL_SECONDS })
  return normalizeModerationPayload(user)
}

module.exports = {
  USER_MOD_KEY_PREFIX,
  getUserModerationFromRedis,
  setUserModerationInRedis,
  getOrCacheUserModeration,
}
