/**
 * Security Headers Middleware
 * Agent 4: Production Deployment
 *
 * Adds security headers to all responses to protect against common attacks.
 */

import type { NextApiRequest, NextApiResponse, NextApiHandler } from 'next';
import { env } from '../config';

interface SecurityHeadersConfig {
  contentSecurityPolicy?: string;
  reportUri?: string;
  enableHSTS?: boolean;
  hstsMaxAge?: number;
  frameOptions?: 'DENY' | 'SAMEORIGIN';
  contentTypeOptions?: boolean;
  xssProtection?: boolean;
  referrerPolicy?: string;
  permissionsPolicy?: string;
}

const DEFAULT_CONFIG: SecurityHeadersConfig = {
  enableHSTS: true,
  hstsMaxAge: 31536000, // 1 year
  frameOptions: 'DENY',
  contentTypeOptions: true,
  xssProtection: true,
  referrerPolicy: 'strict-origin-when-cross-origin',
};

/**
 * Generate Content Security Policy header
 */
function generateCSP(reportUri?: string): string {
  const directives = [
    "default-src 'self'",
    "script-src 'self' 'unsafe-inline' 'unsafe-eval'", // Needed for Next.js
    "style-src 'self' 'unsafe-inline'",
    "img-src 'self' data: blob: https:",
    "font-src 'self' data:",
    "connect-src 'self' https: wss:",
    "media-src 'self'",
    "object-src 'none'",
    "frame-ancestors 'none'",
    "base-uri 'self'",
    "form-action 'self'",
    "upgrade-insecure-requests",
  ];

  if (reportUri) {
    directives.push(`report-uri ${reportUri}`);
  }

  return directives.join('; ');
}

/**
 * Generate Permissions Policy header
 */
function generatePermissionsPolicy(): string {
  const policies = [
    'accelerometer=()',
    'camera=()',
    'geolocation=(self)',
    'gyroscope=()',
    'magnetometer=()',
    'microphone=()',
    'payment=()',
    'usb=()',
  ];

  return policies.join(', ');
}

/**
 * Apply security headers to response
 */
export function applySecurityHeaders(
  res: NextApiResponse,
  config: SecurityHeadersConfig = DEFAULT_CONFIG
): void {
  // Content Security Policy
  const csp = config.contentSecurityPolicy || generateCSP(config.reportUri || env.cspReportUri);
  res.setHeader('Content-Security-Policy', csp);

  // Strict Transport Security (HTTPS)
  if (config.enableHSTS && env.isProduction) {
    res.setHeader(
      'Strict-Transport-Security',
      `max-age=${config.hstsMaxAge}; includeSubDomains; preload`
    );
  }

  // Prevent clickjacking
  res.setHeader('X-Frame-Options', config.frameOptions || 'DENY');

  // Prevent MIME type sniffing
  if (config.contentTypeOptions) {
    res.setHeader('X-Content-Type-Options', 'nosniff');
  }

  // XSS Protection (legacy, but still useful)
  if (config.xssProtection) {
    res.setHeader('X-XSS-Protection', '1; mode=block');
  }

  // Referrer Policy
  res.setHeader('Referrer-Policy', config.referrerPolicy || 'strict-origin-when-cross-origin');

  // Permissions Policy
  res.setHeader(
    'Permissions-Policy',
    config.permissionsPolicy || generatePermissionsPolicy()
  );

  // Remove unnecessary headers
  res.removeHeader('X-Powered-By');
}

/**
 * Security headers middleware for API routes
 */
export function withSecurityHeaders(
  handler: NextApiHandler,
  config?: SecurityHeadersConfig
): NextApiHandler {
  return async (req: NextApiRequest, res: NextApiResponse) => {
    applySecurityHeaders(res, config);
    return handler(req, res);
  };
}

// Export types
export type { SecurityHeadersConfig };
