import { redisConnection, mysqlConnection } from '../config/database';
import { logger } from '../utils/logger';

interface CacheOptions {
  expireTime?: number; // Redis过期时间（秒）
}

class CacheService {
  /**
   * 获取缓存数据
   * 优先级：Redis → MySQL → 数据源
   */
  async get<T>(key: string, symbol: string, type: string, fetchFromSource: () => Promise<T>, options: CacheOptions = {}): Promise<T> {
    try {
      // 1. 先从Redis中读取
      logger.log(`尝试从Redis获取缓存: ${key}`);
      const redisData = await redisConnection.get(key);
      
      if (redisData) {
        logger.log(`从Redis获取缓存成功: ${key}`);
        return JSON.parse(redisData) as T;
      }

      // 2. Redis中不存在，从MySQL中获取
      logger.log(`尝试从MySQL获取缓存: ${symbol}, ${type}`);
      const [mysqlResults]: any = await mysqlConnection.query(
        'SELECT data FROM market_data WHERE symbol = ? AND type = ?',
        [symbol, type]
      );

      if (mysqlResults && mysqlResults.length > 0) {
        const mysqlData = mysqlResults[0].data;
        logger.log(`从MySQL获取缓存成功: ${symbol}, ${type}`);

        // 将MySQL数据同步到Redis
        await this.set(key, mysqlData, options);
        return mysqlData as T;
      }

      // 3. MySQL中也不存在，从数据源获取
      logger.log(`从数据源获取数据: ${key}`);
      const sourceData = await fetchFromSource();

      // 将数据源数据同步到MySQL和Redis
      await this.set(key, sourceData, options);
      await this.saveToMySQL(symbol, type, sourceData);

      return sourceData;
    } catch (error) {
      logger.error(`获取缓存数据失败: ${key}`, error);
      // 出错时直接从数据源获取
      return fetchFromSource();
    }
  }

  /**
   * 设置Redis缓存
   */
  async set(key: string, value: any, options: CacheOptions = {}): Promise<void> {
    try {
      const jsonValue = JSON.stringify(value);
      const redisOptions: any = {};

      if (options.expireTime) {
        redisOptions.ex = options.expireTime;
      }

      await redisConnection.set(key, jsonValue, redisOptions);
      logger.log(`设置Redis缓存成功: ${key}`);
    } catch (error) {
      logger.error(`设置Redis缓存失败: ${key}`, error);
    }
  }

  /**
   * 保存数据到MySQL
   */
  async saveToMySQL(symbol: string, type: string, data: any): Promise<void> {
    try {
      // 使用UPSERT操作，存在则更新，不存在则插入
      await mysqlConnection.query(
        `INSERT INTO market_data (symbol, type, data) 
         VALUES (?, ?, ?) 
         ON DUPLICATE KEY UPDATE data = VALUES(data)`,
        [symbol, type, JSON.stringify(data)]
      );
      logger.log(`保存数据到MySQL成功: ${symbol}, ${type}`);
    } catch (error) {
      logger.error(`保存数据到MySQL失败: ${symbol}, ${type}`, error);
    }
  }

  /**
   * 删除缓存
   */
  async delete(key: string): Promise<void> {
    try {
      await redisConnection.del(key);
      logger.log(`删除Redis缓存成功: ${key}`);
    } catch (error) {
      logger.error(`删除Redis缓存失败: ${key}`, error);
    }
  }

  /**
   * 清除指定类型的缓存
   */
  async clearByType(symbol: string, type: string): Promise<void> {
    try {
      // 清除Redis缓存
      const key = `${symbol}:${type}`;
      await this.delete(key);

      // 清除MySQL缓存
      await mysqlConnection.query(
        'DELETE FROM market_data WHERE symbol = ? AND type = ?',
        [symbol, type]
      );

      logger.log(`清除缓存成功: ${symbol}, ${type}`);
    } catch (error) {
      logger.error(`清除缓存失败: ${symbol}, ${type}`, error);
    }
  }
}

export const cacheService = new CacheService();
export default cacheService;