import { redisService } from '../services/redis.service';

interface CacheOptions {
  ttl: number;           // 缓存时间（秒）
  keyPrefix?: string;    // 键前缀
  keyGenerator?: (ctx: any) => string; // 自定义键生成器
}

/**
 * 缓存中间件
 * @param options 缓存配置
 */
export function createCache(options: CacheOptions) {
  return async (ctx: any, next: any) => {
    // 如果 Redis 不可用，跳过缓存
    if (!redisService.isAvailable()) {
      return await next();
    }

    try {
      // 生成缓存键
      const cacheKey = options.keyGenerator
        ? `${options.keyPrefix || 'cache'}:${options.keyGenerator(ctx)}`
        : `${options.keyPrefix || 'cache'}:${ctx.method}:${ctx.url}`;

      // 尝试从缓存获取
      const cachedData = await redisService.get(cacheKey);
      if (cachedData) {
        ctx.set('X-Cache', 'HIT');
        ctx.body = JSON.parse(cachedData);
        return;
      }

      // 执行请求
      await next();

      // 缓存成功的响应
      if (ctx.status === 200 && ctx.body) {
        await redisService.set(cacheKey, JSON.stringify(ctx.body), options.ttl);
        ctx.set('X-Cache', 'MISS');
      }
    } catch (error) {
      console.error('[Cache] 缓存中间件错误:', (error as Error).message);
      // 缓存失败不影响请求
      return await next();
    }
  };
}

/**
 * 清除缓存中间件
 * @param keyPrefix 键前缀
 */
export function clearCache(keyPrefix: string) {
  return async (ctx: any, next: any) => {
    if (redisService.isAvailable()) {
      await redisService.delPattern(`${keyPrefix}:*`);
    }
    return await next();
  };
}

/**
 * 常用缓存配置
 */

// 用户信息缓存（5 分钟）
export const userCache = createCache({
  ttl: 300,
  keyPrefix: 'user',
  keyGenerator: (ctx) => ctx.state.user?.id || 'anonymous',
});

// 音色列表缓存（1 小时）
export const voiceListCache = createCache({
  ttl: 3600,
  keyPrefix: 'voice:list',
});

// 书籍详情缓存（10 分钟）
export const bookDetailCache = createCache({
  ttl: 600,
  keyPrefix: 'book:detail',
  keyGenerator: (ctx) => ctx.params.id || ctx.query.id,
});

// 热门书籍缓存（5 分钟）
export const hotBooksCache = createCache({
  ttl: 300,
  keyPrefix: 'book:hot',
});

// 会员权益缓存（1 小时）
export const memberBenefitsCache = createCache({
  ttl: 3600,
  keyPrefix: 'member:benefits',
});
