package middleware

import (
	"strings"

	"github.com/gofiber/fiber/v2"
)

// SecurityHeadersMiddleware adds security headers to all responses
func SecurityHeadersMiddleware() fiber.Handler {
	return func(c *fiber.Ctx) error {
		// Prevent MIME type sniffing
		c.Set("X-Content-Type-Options", "nosniff")

		// Prevent clickjacking attacks
		c.Set("X-Frame-Options", "DENY")

		// Content Security Policy
		// Next.js static export injects inline <script> and <style> tags for
		// hydration, so 'unsafe-inline' and 'unsafe-eval' are required.
		// Skip CSP for API responses to avoid "unneeded headers" audit warnings.
		if !strings.HasPrefix(c.Path(), "/api") {
			csp := "default-src 'self'; " +
				"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdnjs.cloudflare.com; " +
				"style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com https://fonts.googleapis.com; " +
				"font-src 'self' https://cdnjs.cloudflare.com https://fonts.gstatic.com; " +
				"img-src 'self' data: https:; " +
				"connect-src 'self' ws: wss:; " +
				"frame-ancestors 'none'; " +
				"base-uri 'self'; " +
				"form-action 'self'; " +
				"object-src 'none'"
			c.Set("Content-Security-Policy", csp)

			// Report-only policy mirrors the enforced CSP with a report-uri so
			// violations are logged without blocking execution.
			reportOnlyCSP := "default-src 'self'; " +
				"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdnjs.cloudflare.com; " +
				"style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com https://fonts.googleapis.com; " +
				"font-src 'self' https://cdnjs.cloudflare.com https://fonts.gstatic.com; " +
				"img-src 'self' data: https:; " +
				"connect-src 'self' ws: wss:; " +
				"frame-ancestors 'none'; " +
				"base-uri 'self'; " +
				"form-action 'self'; " +
				"object-src 'none'; " +
				"report-uri /api/security/csp-report"
			c.Set("Content-Security-Policy-Report-Only", reportOnlyCSP)
		}

		// Strict Transport Security (HSTS)
		// Only enable in production with HTTPS
		forwardedProto := strings.ToLower(strings.TrimSpace(c.Get("X-Forwarded-Proto")))
		if c.Protocol() == "https" || forwardedProto == "https" {
			c.Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
		}

		// Referrer Policy
		c.Set("Referrer-Policy", "strict-origin-when-cross-origin")

		// Permissions Policy (formerly Feature Policy)
		c.Set("Permissions-Policy", "geolocation=(), microphone=(), camera=()")
		c.Set("Cross-Origin-Opener-Policy", "same-origin")
		c.Set("Cross-Origin-Resource-Policy", "same-origin")
		c.Set("X-Permitted-Cross-Domain-Policies", "none")

		// Remove server header to hide technology stack
		c.Set("Server", "")

		return c.Next()
	}
}
