package middleware

import (
	"errors"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"

	"github.com/user-management-system/internal/config"
)

var corsConfig = config.CORSConfig{
	AllowedOrigins:   []string{}, // 默认为空，必须显式配置
	AllowCredentials: false,      // 默认关闭凭证，必须显式启用
}

func validateCORSConfig(cfg config.CORSConfig) error {
	for _, origin := range cfg.AllowedOrigins {
		if origin == "*" && cfg.AllowCredentials {
			return errors.New("CORS 配置错误: AllowedOrigins 包含 '*' 时不能启用 AllowCredentials")
		}
	}
	return nil
}

func SetCORSConfig(cfg config.CORSConfig) error {
	if err := validateCORSConfig(cfg); err != nil {
		return err
	}
	corsConfig = cfg
	return nil
}

func CORS() gin.HandlerFunc {
	return func(c *gin.Context) {
		cfg := corsConfig

		origin := c.GetHeader("Origin")
		if origin != "" {
			allowOrigin, allowed := resolveAllowedOrigin(origin, cfg.AllowedOrigins, cfg.AllowCredentials)
			if !allowed {
				if c.Request.Method == http.MethodOptions {
					c.AbortWithStatus(http.StatusForbidden)
					return
				}
				c.AbortWithStatus(http.StatusForbidden)
				return
			}
			c.Writer.Header().Set("Access-Control-Allow-Origin", allowOrigin)
			if cfg.AllowCredentials {
				c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
			}
		}

		if c.Request.Method == http.MethodOptions {
			c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
			c.Writer.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type, X-Requested-With, X-CSRF-Token")
			c.Writer.Header().Set("Access-Control-Max-Age", "3600")
			c.AbortWithStatus(http.StatusNoContent)
			return
		}

		c.Next()
	}
}

func resolveAllowedOrigin(origin string, allowedOrigins []string, allowCredentials bool) (string, bool) {
	for _, allowed := range allowedOrigins {
		if allowed == "*" {
			if allowCredentials {
				return origin, true
			}
			return "*", true
		}
		if strings.EqualFold(origin, allowed) {
			return origin, true
		}
	}
	return "", false
}
