// src/middleware/authMiddleware.js
const jwt = require('jsonwebtoken');
// === SECURITY HARDENING: JWT KEY ROTATION ===
const {
  getKeySecret,
  getAllKeys,
  validateTokenClaims,
} = require('../services/jwtKeys');

function authMiddleware(req, res, next) {
  const auth = req.headers.authorization || '';
  const token = auth.startsWith('Bearer ') ? auth.slice(7) : null;

  if (!token) {
    return res.status(401).json({ error: 'Missing Authorization header' });
  }

  // === SECURITY HARDENING: JWT KEY ROTATION ===
  // Decode token to get key ID from header
  let decoded;
  try {
    decoded = jwt.decode(token, { complete: true });
    if (!decoded || !decoded.header) {
      return res.status(401).json({ error: 'Invalid token format' });
    }
  } catch (err) {
    return res.status(401).json({ error: 'Invalid token' });
  }

  // Get secret for the key ID (if present) or try all keys
  const keyId = decoded.header.kid;
  let payload = null;
  let verified = false;

  if (keyId) {
    const secret = getKeySecret(keyId);
    if (secret) {
      try {
        payload = jwt.verify(token, secret);
        verified = true;
      } catch (err) {
        // Key ID specified but verification failed
        return res.status(401).json({ error: 'Invalid or expired token' });
      }
    }
  }

  // If key ID not found or not specified, try all keys (for rotation support)
  if (!verified) {
    const allKeys = getAllKeys();
    for (const [kid, keySecret] of Object.entries(allKeys)) {
      try {
        payload = jwt.verify(token, keySecret);
        verified = true;
        break;
      } catch (err) {
        // Try next key
        continue;
      }
    }
  }

  if (!verified || !payload) {
    return res.status(401).json({ error: 'Invalid or expired token' });
  }

  // === SECURITY HARDENING: JWT KEY ROTATION ===
  // Validate JWT claims (iss, aud, exp, iat, nbf)
  const claimsValidation = validateTokenClaims(payload);
  if (!claimsValidation.valid) {
    return res.status(401).json({ error: 'Invalid token claims' });
  }

  req.user = {
    id: payload.sub,
    phone_number: payload.phone_number,
    role: payload.role,
    user_type: payload.user_type,
    // === SECURITY HARDENING: ACCESS TOKEN REPLAY MITIGATION ===
    high_assurance: payload.high_assurance || false,
  };
  next();
}

module.exports = authMiddleware;
