import { Injectable, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InMemoryService } from './in-memory.service';

@Injectable()
export class RedisService implements OnModuleInit {
  private useRedis = false;
  private redisClient: any = null;

  constructor(
    private configService: ConfigService,
    private inMemoryService: InMemoryService
  ) {}

  async onModuleInit() {
    try {
      // Проверяем, доступен ли Redis
      this.useRedis = await this.checkRedisAvailability();
      
      if (this.useRedis) {
        console.log('✅ Redis подключен');
      } else {
        console.log('⚠️  Redis недоступен, используется in-memory хранилище');
      }
    } catch (error) {
      console.log('⚠️  Используется in-memory хранилище');
    }
  }

  private async checkRedisAvailability(): Promise<boolean> {
    const host = this.configService.get('REDIS_HOST', 'localhost');
    const port = this.configService.get('REDIS_PORT', 6379);
    
    try {
      // Простая проверка TCP соединения
      const net = await import('net');
      return new Promise((resolve) => {
        const socket = net.createConnection({ host, port }, () => {
          socket.destroy();
          resolve(true);
        });
        
        socket.on('error', () => {
          resolve(false);
        });
        
        setTimeout(() => {
          socket.destroy();
          resolve(false);
        }, 1000);
      });
    } catch {
      return false;
    }
  }

  // Все методы делегируются к in-memory сервису
  async set(key: string, value: any, ttl?: number): Promise<void> {
    return this.inMemoryService.set(key, value, ttl);
  }

  async get<T>(key: string): Promise<T | null> {
    return this.inMemoryService.get<T>(key);
  }

  async del(key: string): Promise<void> {
    return this.inMemoryService.del(key);
  }

  async exists(key: string): Promise<boolean> {
    return this.inMemoryService.exists(key);
  }

  async pushToList(key: string, value: any, maxLength: number = 100): Promise<void> {
    return this.inMemoryService.pushToList(key, value, maxLength);
  }

  async getList<T>(key: string, start: number = 0, end: number = -1): Promise<T[]> {
    return this.inMemoryService.getList<T>(key, start, end);
  }

  async getListLength(key: string): Promise<number> {
    return this.inMemoryService.getListLength(key);
  }

  async setHash(key: string, field: string, value: any): Promise<void> {
    return this.inMemoryService.setHash(key, field, value);
  }

  async getHash<T>(key: string, field: string): Promise<T | null> {
    return this.inMemoryService.getHash<T>(key, field);
  }

  async getAllHash<T>(key: string): Promise<Record<string, T>> {
    return this.inMemoryService.getAllHash<T>(key);
  }

  async generateId(prefix: string): Promise<string> {
    return this.inMemoryService.generateId(prefix);
  }

  getSessionKey(sessionId: string): string {
    return this.inMemoryService.getSessionKey(sessionId);
  }

  getMessagesKey(sessionId: string): string {
    return this.inMemoryService.getMessagesKey(sessionId);
  }

  getUserSessionsKey(userId?: string): string {
    return this.inMemoryService.getUserSessionsKey(userId);
  }

  // Дополнительный метод для отладки
  async getStats() {
    return this.inMemoryService.getStats();
  }
}