const { redis } = require('../config/services');
const env = require('../config/env');
const logger = require('../utils/logger');

const CACHE_TTL = Number.isFinite(env.redisCacheTtlSeconds) ? env.redisCacheTtlSeconds : 21600;

const ensureRedisConnection = async () => {
  if (!redis) return;
  if (redis.status === 'ready') return;
  if (!redis.status || redis.status === 'end') {
    await redis.connect();
  }
};

const readCache = async (cacheKey) => {
  try {
    await ensureRedisConnection();
    const cached = await redis.get(cacheKey);
    if (cached) {
      logger.cacheHit(cacheKey);
      return JSON.parse(cached);
    }
  } catch (error) {
    logger.warn(`Redis cache okunurken hata: ${error.message}`);
  }
  return null;
};

const writeCache = async (cacheKey, payload) => {
  try {
    await ensureRedisConnection();
    await redis.set(cacheKey, JSON.stringify(payload), 'EX', CACHE_TTL);
    logger.cacheMiss(cacheKey);
  } catch (error) {
    logger.warn(`Redis cache yazilirken hata: ${error.message}`);
  }
};

const normalizeLocales = (locales = []) => [...locales].map((locale) => locale.toLowerCase()).sort().join(',');
const encodeText = (value = '') => encodeURIComponent(value.trim().toLowerCase());

const buildIsbnCacheKey = (isbn, locales, includeGemini) => {
  const geminiFlag = includeGemini ? '1' : '0';
  return `book:isbn:${isbn}:loc=${normalizeLocales(locales)}:gem=${geminiFlag}`;
};

const buildTitleCacheKey = ({ title, locales, includeGemini, limit }) => {
  const geminiFlag = includeGemini ? '1' : '0';
  return `book:title:q=${encodeText(title)}:loc=${normalizeLocales(locales)}:gem=${geminiFlag}:limit=${limit}`;
};

const buildFilterCacheKey = ({ title, published, locales, includeGemini, limit }) => {
  const geminiFlag = includeGemini ? '1' : '0';
  return `book:filter:q=${encodeText(title)}:pub=${encodeText(published)}:loc=${normalizeLocales(locales)}:gem=${geminiFlag}:limit=${limit}`;
};

const getIsbnCache = (isbn, locales, includeGemini) =>
  readCache(buildIsbnCacheKey(isbn, locales, includeGemini));
const setIsbnCache = (isbn, locales, includeGemini, payload) =>
  writeCache(buildIsbnCacheKey(isbn, locales, includeGemini), payload);

const getTitleCache = (params) => readCache(buildTitleCacheKey(params));
const setTitleCache = (params, payload) => writeCache(buildTitleCacheKey(params), payload);

const getFilterCache = (params) => readCache(buildFilterCacheKey(params));
const setFilterCache = (params, payload) => writeCache(buildFilterCacheKey(params), payload);

module.exports = {
  getIsbnCache,
  setIsbnCache,
  getTitleCache,
  setTitleCache,
  getFilterCache,
  setFilterCache,
  ensureRedisConnection
};
