import { Request, Response, NextFunction } from 'express';
import { getRedisClient } from '../config/redis';
import { logger } from '../config/logger';

export const cacheMiddleware = (ttlSeconds: number = 300) => {
  return async (req: Request, res: Response, next: NextFunction) => {
    // Only cache GET requests
    if (req.method !== 'GET') {
      return next();
    }

    const redis = getRedisClient();
    if (!redis || !redis.isOpen) {
      return next();
    }

    const cacheKey = `cache:${req.originalUrl || req.url}`;

    try {
      const cachedData = await redis.get(cacheKey);
      if (cachedData) {
        logger.info(`[Redis Cache HIT] Key: ${cacheKey}`);
        res.setHeader('X-Cache', 'HIT');
        res.setHeader('Cache-Control', `public, max-age=${ttlSeconds}`);
        return res.status(200).json(JSON.parse(cachedData));
      }

      logger.info(`[Redis Cache MISS] Key: ${cacheKey}`);
      res.setHeader('X-Cache', 'MISS');

      // Override res.json to capture response and store in Redis
      const originalJson = res.json.bind(res);
      res.json = (body: any) => {
        if (res.statusCode === 200 && body && body.success) {
          redis.setEx(cacheKey, ttlSeconds, JSON.stringify(body)).catch((err: unknown) => {
            logger.error('Redis SetEx Error:', err);
          });
        }
        return originalJson(body);
      };

      next();
    } catch (error) {
      logger.error('Cache Middleware Error:', error);
      next();
    }
  };
};
