const CacheUtil = require('../utils/cache');
const logger = require('../config/logger');

/**
 * Service data caching strategies
 */
class CacheService {
  // Cache key prefixes
  static KEYS = {
    SERVICE_LIST: 'services:list',
    SERVICE_DETAIL: 'services:detail',
    CATEGORY_LIST: 'categories:list',
    SERVICE_BY_CATEGORY: 'services:category',
  };

  // Cache TTL in seconds
  static TTL = {
    SERVICE_LIST: 3600, // 1 hour
    SERVICE_DETAIL: 3600, // 1 hour
    CATEGORY_LIST: 7200, // 2 hours
    SERVICE_BY_CATEGORY: 3600, // 1 hour
  };

  /**
   * Get cached service list
   * @param {Object} params - Query parameters (page, limit, categoryId)
   * @returns {Promise<any>} - Cached service list or null
   */
  static async getServiceList(params = {}) {
    const key = this.buildServiceListKey(params);
    return await CacheUtil.get(key);
  }

  /**
   * Cache service list
   * @param {Object} params - Query parameters
   * @param {any} data - Service list data
   * @returns {Promise<boolean>} - Success status
   */
  static async setServiceList(params, data) {
    const key = this.buildServiceListKey(params);
    return await CacheUtil.set(key, data, this.TTL.SERVICE_LIST);
  }

  /**
   * Get cached service detail
   * @param {string} serviceId - Service ID
   * @returns {Promise<any>} - Cached service detail or null
   */
  static async getServiceDetail(serviceId) {
    const key = `${this.KEYS.SERVICE_DETAIL}:${serviceId}`;
    return await CacheUtil.get(key);
  }

  /**
   * Cache service detail
   * @param {string} serviceId - Service ID
   * @param {any} data - Service detail data
   * @returns {Promise<boolean>} - Success status
   */
  static async setServiceDetail(serviceId, data) {
    const key = `${this.KEYS.SERVICE_DETAIL}:${serviceId}`;
    return await CacheUtil.set(key, data, this.TTL.SERVICE_DETAIL);
  }

  /**
   * Get cached category list
   * @returns {Promise<any>} - Cached category list or null
   */
  static async getCategoryList() {
    return await CacheUtil.get(this.KEYS.CATEGORY_LIST);
  }

  /**
   * Cache category list
   * @param {any} data - Category list data
   * @returns {Promise<boolean>} - Success status
   */
  static async setCategoryList(data) {
    return await CacheUtil.set(
      this.KEYS.CATEGORY_LIST,
      data,
      this.TTL.CATEGORY_LIST
    );
  }

  /**
   * Get cached services by category
   * @param {string} categoryId - Category ID
   * @param {Object} params - Query parameters
   * @returns {Promise<any>} - Cached services or null
   */
  static async getServicesByCategory(categoryId, params = {}) {
    const key = `${this.KEYS.SERVICE_BY_CATEGORY}:${categoryId}:${JSON.stringify(params)}`;
    return await CacheUtil.get(key);
  }

  /**
   * Cache services by category
   * @param {string} categoryId - Category ID
   * @param {Object} params - Query parameters
   * @param {any} data - Services data
   * @returns {Promise<boolean>} - Success status
   */
  static async setServicesByCategory(categoryId, params, data) {
    const key = `${this.KEYS.SERVICE_BY_CATEGORY}:${categoryId}:${JSON.stringify(params)}`;
    return await CacheUtil.set(key, data, this.TTL.SERVICE_BY_CATEGORY);
  }

  /**
   * Invalidate all service caches
   * @returns {Promise<number>} - Number of keys deleted
   */
  static async invalidateServiceCache() {
    try {
      const patterns = [
        `${this.KEYS.SERVICE_LIST}*`,
        `${this.KEYS.SERVICE_DETAIL}*`,
        `${this.KEYS.SERVICE_BY_CATEGORY}*`,
      ];

      let totalDeleted = 0;
      for (const pattern of patterns) {
        const deleted = await CacheUtil.deletePattern(pattern);
        totalDeleted += deleted;
      }

      logger.info(`Invalidated ${totalDeleted} service cache keys`);
      return totalDeleted;
    } catch (error) {
      logger.error('Error invalidating service cache:', error);
      return 0;
    }
  }

  /**
   * Invalidate category cache
   * @returns {Promise<boolean>} - Success status
   */
  static async invalidateCategoryCache() {
    return await CacheUtil.delete(this.KEYS.CATEGORY_LIST);
  }

  /**
   * Invalidate specific service cache
   * @param {string} serviceId - Service ID
   * @returns {Promise<boolean>} - Success status
   */
  static async invalidateServiceDetail(serviceId) {
    const key = `${this.KEYS.SERVICE_DETAIL}:${serviceId}`;
    return await CacheUtil.delete(key);
  }

  /**
   * Build service list cache key
   * @param {Object} params - Query parameters
   * @returns {string} - Cache key
   */
  static buildServiceListKey(params) {
    const { page = 1, limit = 10, categoryKey = 'all' } = params;
    return `${this.KEYS.SERVICE_LIST}:${categoryKey}:${page}:${limit}`;
  }
}

module.exports = CacheService;
