import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Inject, Injectable } from '@nestjs/common';
import type { Cache } from 'cache-manager';

@Injectable()
export class RedisService {
  constructor(@Inject(CACHE_MANAGER) private readonly cacheManager: Cache) {}

  async get<T>(key: string): Promise<T | undefined> {
    return await this.cacheManager.get<T>(key);
  }

  async set<T>(key: string, value: T, ttl?: number): Promise<void> {
    await this.cacheManager.set(key, value, ttl);
  }

  async del(key: string): Promise<void> {
    await this.cacheManager.del(key);
  }

  async wrap<T>(key: string, fn: () => Promise<T>, ttl?: number): Promise<T> {
    return await this.cacheManager.wrap(key, fn, ttl);
  }

  /**
   * Almacena un código de verificación en caché
   */
  async setVerificationCode(userId: string, code: string, ttl = 600000): Promise<void> {
    await this.set(`verification:${userId}`, code, ttl);
  }

  /**
   * Obtiene un código de verificación de la caché
   */
  async getVerificationCode(userId: string): Promise<string | undefined> {
    return await this.get<string>(`verification:${userId}`);
  }

  /**
   * Elimina un código de verificación de la caché
   */
  async deleteVerificationCode(userId: string): Promise<void> {
    await this.del(`verification:${userId}`);
  }

  /**
   * Limpia todo el cache de Redis
   */
  async reset(): Promise<void> {
    const manager = this.cacheManager as unknown as { store?: { reset?: () => Promise<void> } };
    if (manager.store?.reset) {
      await manager.store.reset();
    }
  }

  /**
   * Invalida el cache de referenciales
   */
  async invalidateReferenciales(): Promise<void> {
    await this.del('referenciales:all');
  }
}
