// Package middleware provides HTTP middleware for services.
package middleware

import (
	"net/http"

	"github.com/go-chi/cors"
)

// CORSConfig configures CORS behavior for HTTP services.
// Used to control cross-origin requests from browsers.
type CORSConfig struct {
	// AllowedOrigins lists domains allowed to make cross-origin requests.
	// Use []string{"*"} for open access (dev/staging), specific domains for production.
	// Example: []string{"https://app.example.com", "https://admin.example.com"}
	AllowedOrigins []string

	// AllowedMethods lists HTTP methods that can be used in cross-origin requests.
	// Example: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}
	AllowedMethods []string

	// AllowedHeaders lists request headers that can be included in cross-origin requests.
	// Must include headers used by services (Authorization, X-Request-ID, etc.)
	AllowedHeaders []string

	// ExposedHeaders lists response headers that the browser can expose to JavaScript.
	// Useful for pagination headers, custom metadata, etc.
	ExposedHeaders []string

	// AllowCredentials controls whether browsers can send credentials (cookies, auth headers)
	// in cross-origin requests. MUST be false when AllowedOrigins is "*".
	AllowCredentials bool

	// MaxAge specifies how long (in seconds) browsers can cache preflight responses.
	// Reduces OPTIONS requests for the same resource.
	MaxAge int
}

// DefaultCORSConfig returns sensible defaults for services.
// Designed for local development and staging environments.
//
// Defaults:
//   - AllowedOrigins: ["*"] (override in production to specific domains)
//   - AllowedMethods: GET, POST, PUT, PATCH, DELETE, OPTIONS
//   - AllowedHeaders: ["*"] (allows any header - simplest for development)
//   - ExposedHeaders: Link (for pagination)
//   - AllowCredentials: false (required when AllowedOrigins is "*")
//   - MaxAge: 300 seconds (5 minutes)
//
// Production services should override AllowedOrigins with specific domains,
// set AllowCredentials: true if needed, and optionally restrict AllowedHeaders.
func DefaultCORSConfig() CORSConfig {
	return CORSConfig{
		AllowedOrigins:   []string{"*"},
		AllowedMethods:   []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
		AllowedHeaders:   []string{"*"},
		ExposedHeaders:   []string{"Link"},
		AllowCredentials: false,
		MaxAge:           300,
	}
}

// CORS returns middleware that handles CORS headers for cross-origin requests.
// Uses github.com/go-chi/cors under the hood for RFC compliance.
//
// The middleware:
//   - Handles preflight OPTIONS requests automatically
//   - Sets Access-Control-* headers on actual requests
//   - Validates origins against AllowedOrigins
//   - Caches preflight responses according to MaxAge
//
// Usage:
//
//	r := chi.NewRouter()
//	r.Use(middleware.CORS(middleware.DefaultCORSConfig()))
//
// Production example:
//
//	cfg := middleware.CORSConfig{
//	    AllowedOrigins:   []string{"https://app.example.com"},
//	    AllowedMethods:   []string{"GET", "POST", "PUT", "DELETE"},
//	    AllowedHeaders:   []string{"Content-Type", "Authorization"},
//	    AllowCredentials: true,
//	    MaxAge:           600,
//	}
//	r.Use(middleware.CORS(cfg))
func CORS(cfg CORSConfig) func(http.Handler) http.Handler {
	c := cors.New(cors.Options{
		AllowedOrigins:   cfg.AllowedOrigins,
		AllowedMethods:   cfg.AllowedMethods,
		AllowedHeaders:   cfg.AllowedHeaders,
		ExposedHeaders:   cfg.ExposedHeaders,
		AllowCredentials: cfg.AllowCredentials,
		MaxAge:           cfg.MaxAge,
	})

	return c.Handler
}
