import { pool } from '../db/connection.js';

// In-memory cache for idempotency keys (in production, use Redis or similar)
const idempotencyCache = new Map();

export const requireIdempotencyKey = async (req, res, next) => {
  // Only apply to POST requests
  if (req.method !== 'POST') {
    return next();
  }

  const idempotencyKey = req.headers['x-idempotency-key'];
  
  // If no key provided, proceed normally (non-idempotent request)
  if (!idempotencyKey) {
    return next();
  }

  try {
    // Check if this key was used before
    const [existing] = await pool.query(
      'SELECT id, response_body, created_at FROM idempotency_keys WHERE key = ?',
      [idempotencyKey]
    );

    if (existing.length > 0) {
      // Key already exists, return cached response
      const cachedResponse = JSON.parse(existing[0].response_body);
      return res.status(cachedResponse.status).json(cachedResponse.body);
    }

    // Store the key with a placeholder for response
    await pool.query(
      'INSERT INTO idempotency_keys (key, created_at) VALUES (?, NOW())',
      [idempotencyKey]
    );

    // Add a function to cache the response
    req.cacheIdempotentResponse = async (status, body) => {
      const responseBody = JSON.stringify({ status, body });
      await pool.query(
        'UPDATE idempotency_keys SET response_body = ? WHERE key = ?',
        [responseBody, idempotencyKey]
      );
    };

    next();
  } catch (error) {
    console.error('Error in idempotency middleware:', error);
    // If database fails, proceed without idempotency
    next();
  }
};

// Helper function to create a unique key for a request
export const generateIdempotencyKey = (req) => {
  // Create a simple hash of the request data
  const { method, url, body } = req;
  const keyString = `${method}-${url}-${JSON.stringify(body)}`;
  
  // Simple hash function (in production, use proper hashing)
  let hash = 0;
  for (let i = 0; i < keyString.length; i++) {
    const char = keyString.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash |= 0; // Convert to 32bit integer
  }
  
  return `idempotency-${Math.abs(hash)}`;
};