package api

import (
	"log"
	"net/http"
	"strings"
	"time"
)

// CORSMiddleware adds CORS headers to enable browser requests
func CORSMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		origin := r.Header.Get("Origin")

		// In development mode, allow all localhost origins including demo sites
		if isLocalhostOrigin(origin) {
			w.Header().Set("Access-Control-Allow-Origin", origin)
		} else {
			// Fallback to wildcard for development (can be restricted in production)
			w.Header().Set("Access-Control-Allow-Origin", "*")
		}

		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
		w.Header().Set("Access-Control-Allow-Credentials", "true")

		// Note: Explicit OPTIONS handling is done via routes, not here
		next.ServeHTTP(w, r)
	})
}

// LoggingMiddleware logs HTTP requests
func LoggingMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()

		// Create a response writer wrapper to capture status code
		wrapper := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}

		next.ServeHTTP(wrapper, r)

		log.Printf("%s %s %d %v", r.Method, r.URL.Path, wrapper.statusCode, time.Since(start))
	})
}

// responseWriter wraps http.ResponseWriter to capture status code
type responseWriter struct {
	http.ResponseWriter
	statusCode int
}

func (rw *responseWriter) WriteHeader(code int) {
	rw.statusCode = code
	rw.ResponseWriter.WriteHeader(code)
}

// ContentTypeMiddleware ensures JSON responses have proper content type
func ContentTypeMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Set default content type for API responses only, not static sites
		if r.URL.Path != "/" &&
			!strings.HasPrefix(r.URL.Path, "/sites/") &&
			!strings.HasPrefix(r.URL.Path, "/insertr.js") &&
			!strings.HasPrefix(r.URL.Path, "/insertr.css") &&
			(r.Method == "GET" || r.Method == "POST" || r.Method == "PUT") {
			w.Header().Set("Content-Type", "application/json")
		}

		next.ServeHTTP(w, r)
	})
}

// HealthMiddleware provides a simple health check endpoint
func HealthMiddleware() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`{"status":"healthy","service":"insertr-server"}`))
	}
}

// CORSPreflightHandler handles CORS preflight requests (OPTIONS)
func CORSPreflightHandler(w http.ResponseWriter, r *http.Request) {
	origin := r.Header.Get("Origin")

	// Allow localhost and 127.0.0.1 on common development ports
	allowedOrigins := []string{
		"http://localhost:3000",
		"http://localhost:8080",
		"http://127.0.0.1:3000",
		"http://127.0.0.1:8080",
	}

	// Check if origin is allowed
	originAllowed := false
	for _, allowed := range allowedOrigins {
		if origin == allowed {
			originAllowed = true
			break
		}
	}

	if originAllowed {
		w.Header().Set("Access-Control-Allow-Origin", origin)
	} else {
		// Fallback to wildcard for development
		w.Header().Set("Access-Control-Allow-Origin", "*")
	}

	w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
	w.Header().Set("Access-Control-Allow-Credentials", "true")
	w.Header().Set("Access-Control-Max-Age", "86400") // Cache preflight for 24 hours

	w.WriteHeader(http.StatusOK)
}

// isLocalhostOrigin checks if an origin is a localhost/127.0.0.1 development origin
func isLocalhostOrigin(origin string) bool {
	if origin == "" {
		return false
	}

	// Allow localhost and 127.0.0.1 on any port for development
	return strings.HasPrefix(origin, "http://localhost:") ||
		strings.HasPrefix(origin, "https://localhost:") ||
		strings.HasPrefix(origin, "http://127.0.0.1:") ||
		strings.HasPrefix(origin, "https://127.0.0.1:") ||
		origin == "http://localhost" ||
		origin == "https://localhost" ||
		origin == "http://127.0.0.1" ||
		origin == "https://127.0.0.1"
}
