package middleware

import (
	"net/http"

	"metazone.cc/metalab/internal/common"
	"metazone.cc/metalab/internal/config"
	"metazone.cc/metalab/internal/session"

	"github.com/gin-gonic/gin"
)

// AuthMiddleware 认证中间件（结构体模式，持有 SessionManager）
type AuthMiddleware struct {
	cfg             *config.Config
	sessionManager  *session.Manager
}

// NewAuthMiddleware 构造函数
func NewAuthMiddleware(cfg *config.Config, sm *session.Manager) *AuthMiddleware {
	return &AuthMiddleware{cfg: cfg, sessionManager: sm}
}

// Required 登录认证中间件：读 session cookie → 验证会话 → 注入用户信息
// 验证失败 → 清除 cookie → 返回 401
func (am *AuthMiddleware) Required() gin.HandlerFunc {
	return func(c *gin.Context) {
		sid, err := c.Cookie(common.SessionCookieName)
		if err != nil || sid == "" {
			common.ClearSessionCookie(c, am.cfg)
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
				"success": false, "message": "登录已过期，请重新登录",
			})
			return
		}

		s, err := am.sessionManager.Validate(sid)
		if err != nil || s == nil {
			common.ClearSessionCookie(c, am.cfg)
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
				"success": false, "message": "登录已过期，请重新登录",
			})
			return
		}

		injectSessionContext(c, s)
		c.Next()
	}
}

// Optional 可选认证：已登录则注入用户信息，未登录也放行
func (am *AuthMiddleware) Optional() gin.HandlerFunc {
	return func(c *gin.Context) {
		sid, err := c.Cookie(common.SessionCookieName)
		if err != nil || sid == "" {
			c.Next()
			return
		}

		s, err := am.sessionManager.Validate(sid)
		if err != nil || s == nil {
			common.ClearSessionCookie(c, am.cfg)
			c.Next()
			return
		}

		injectSessionContext(c, s)
		c.Next()
	}
}

// injectSessionContext 将会话中的用户信息注入 gin context
func injectSessionContext(c *gin.Context, s *session.Session) {
	if s == nil {
		return
	}
	c.Set("uid", s.UserID)
	c.Set("email", s.Email)
	c.Set("username", s.Username)
	c.Set("role", s.Role)
	c.Set("sid", s.ID)
}
