package middleware

import (
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/gouki/lunar-server/internal/config"
	"github.com/gouki/lunar-server/internal/service"
)

// CORS 跨域中间件；可通过 CORS_ORIGINS 配置允许的源（逗号分隔），未配置时保持 *
func CORS() gin.HandlerFunc {
	cfg := config.Load()
	origins := strings.TrimSpace(cfg.Server.CORSOrigins)
	allowAll := origins == ""
	allowed := map[string]bool{}
	if !allowAll {
		for _, o := range strings.Split(origins, ",") {
			o = strings.TrimSpace(o)
			if o != "" {
				allowed[o] = true
			}
		}
	}

	return func(c *gin.Context) {
		origin := c.GetHeader("Origin")
		if origin != "" {
			if allowAll {
				c.Header("Access-Control-Allow-Origin", "*")
			} else if allowed[origin] {
				c.Header("Access-Control-Allow-Origin", origin)
				c.Header("Vary", "Origin")
			} else {
				// 非白名单源：不输出 CORS 头，浏览器会拦截跨域请求
				if c.Request.Method == "OPTIONS" {
					c.AbortWithStatus(http.StatusNoContent)
					return
				}
				c.Next()
				return
			}
			c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
			c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-Pay-Sign")
		}

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
			return
		}

		c.Next()
	}
}

// bearerToken 从 Authorization 头提取 Bearer token，格式错误时返回 ok=false 并已应答
func bearerToken(c *gin.Context) (string, bool) {
	authHeader := c.GetHeader("Authorization")
	if authHeader == "" {
		c.JSON(http.StatusUnauthorized, gin.H{
			"code": 401,
			"msg":  "未授权",
		})
		c.Abort()
		return "", false
	}

	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "Bearer") {
		c.JSON(http.StatusUnauthorized, gin.H{
			"code": 401,
			"msg":  "token格式错误",
		})
		c.Abort()
		return "", false
	}
	return parts[1], true
}

// Auth JWT认证中间件
func Auth() gin.HandlerFunc {
	return func(c *gin.Context) {
		tokenString, ok := bearerToken(c)
		if !ok {
			return
		}

		cfg := config.Load()
		userService := service.NewUserService()
		userID, err := userService.ParseToken(tokenString, cfg.JWT.Secret)
		if err != nil {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "token无效",
			})
			c.Abort()
			return
		}

		c.Set("userID", userID)
		c.Next()
	}
}

// AdminAuth 管理员认证中间件：要求携带 role=admin 的 JWT（Authorization 头或 HttpOnly Cookie）
func AdminAuth() gin.HandlerFunc {
	return func(c *gin.Context) {
		tokenString := ""
		authHeader := c.GetHeader("Authorization")
		if strings.HasPrefix(authHeader, "Bearer ") {
			tokenString = strings.TrimPrefix(authHeader, "Bearer ")
		} else {
			// 浏览器导航场景：登录时写入的 HttpOnly Cookie
			tokenString, _ = c.Cookie(service.AdminTokenCookie)
		}

		if tokenString == "" {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "需要管理员权限",
			})
			c.Abort()
			return
		}

		cfg := config.Load()
		userService := service.NewUserService()
		if !userService.IsAdminToken(tokenString, cfg.JWT.Secret) {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": 401,
				"msg":  "需要管理员权限",
			})
			c.Abort()
			return
		}

		c.Next()
	}
}

// RateLimit 限流中间件
func RateLimit() gin.HandlerFunc {
	return func(c *gin.Context) {
		// TODO: 实现限流
		c.Next()
	}
}
