const crypto = require("crypto")
const axios = require("axios")
const { getRedisClient } = require("./client")

const IMAGE_KEY_PREFIX = "cache:deal_create:image:"
const DEFAULT_TTL_SECONDS = 5 * 60
const MAX_IMAGE_BYTES = 2 * 1024 * 1024

function createRedisClient() {
  return getRedisClient()
}

function normalizeUrl(rawUrl) {
  if (!rawUrl || typeof rawUrl !== "string") return null
  try {
    const url = new URL(rawUrl)
    if (!["http:", "https:"].includes(url.protocol)) return null
    const hostname = url.hostname.toLowerCase()
    const pathname = url.pathname || "/"
    const search = url.search || ""
    return `${url.protocol}//${hostname}${pathname}${search}`
  } catch {
    return null
  }
}

function buildKey(normalizedUrl) {
  const hash = crypto.createHash("sha1").update(normalizedUrl).digest("hex")
  return `${IMAGE_KEY_PREFIX}${hash}`
}

async function cacheImageFromUrl(rawUrl, { ttlSeconds = DEFAULT_TTL_SECONDS } = {}) {
  const normalized = normalizeUrl(rawUrl)
  if (!normalized) return null

  const key = buildKey(normalized)
  const redis = createRedisClient()

  try {
    const cached = await redis.get(key)
    if (cached) return { key: key.replace(IMAGE_KEY_PREFIX, ""), cached: true }

    const response = await axios.get(normalized, {
      responseType: "arraybuffer",
      timeout: 15000,
      maxContentLength: MAX_IMAGE_BYTES,
      maxBodyLength: MAX_IMAGE_BYTES,
      validateStatus: (status) => status >= 200 && status < 300,
    })

    const contentType = String(response.headers?.["content-type"] || "")
    if (!contentType.startsWith("image/")) return null

    const buffer = Buffer.from(response.data || [])
    if (!buffer.length || buffer.length > MAX_IMAGE_BYTES) return null

    const payload = JSON.stringify({
      ct: contentType,
      b64: buffer.toString("base64"),
    })
    await redis.set(key, payload, "EX", Number(ttlSeconds) || DEFAULT_TTL_SECONDS)
    return { key: key.replace(IMAGE_KEY_PREFIX, ""), cached: false }
  } catch {
    return null
  } finally {}
}

async function getCachedImageByKey(hashKey) {
  if (!hashKey || typeof hashKey !== "string") return null
  const redis = createRedisClient()
  const key = `${IMAGE_KEY_PREFIX}${hashKey}`
  try {
    const raw = await redis.get(key)
    if (!raw) return null
    const parsed = JSON.parse(raw)
    if (!parsed?.ct || !parsed?.b64) return null
    return { contentType: parsed.ct, buffer: Buffer.from(parsed.b64, "base64") }
  } catch {
    return null
  } finally {}
}

module.exports = {
  cacheImageFromUrl,
  getCachedImageByKey,
}
