// Filename: internal/webhandlers/auth_handler.go

package webhandlers

import (
	"gemini-balancer/internal/middleware"
	"gemini-balancer/internal/service"
	"net/http"
	"strings"

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

// WebAuthHandler Web 认证处理器
type WebAuthHandler struct {
	securityService *service.SecurityService
	logger          *logrus.Logger
}

// NewWebAuthHandler 创建 WebAuthHandler
func NewWebAuthHandler(securityService *service.SecurityService) *WebAuthHandler {
	logger := logrus.New()
	logger.SetLevel(logrus.InfoLevel)

	return &WebAuthHandler{
		securityService: securityService,
		logger:          logger,
	}
}

// ShowLoginPage 显示登录页面
func (h *WebAuthHandler) ShowLoginPage(c *gin.Context) {
	errMsg := c.Query("error")

	// 验证重定向路径（防止开放重定向攻击）
	redirectPath := h.validateRedirectPath(c.Query("redirect"))

	// 如果已登录，直接重定向
	if cookie := middleware.ExtractTokenFromCookie(c); cookie != "" {
		if _, err := h.securityService.AuthenticateToken(cookie); err == nil {
			c.Redirect(http.StatusFound, redirectPath)
			return
		}
	}

	c.HTML(http.StatusOK, "auth.html", gin.H{
		"error":    errMsg,
		"redirect": redirectPath,
	})
}

// HandleLogin 已废弃（项目无用户名系统）
func (h *WebAuthHandler) HandleLogin(c *gin.Context) {
	c.Redirect(http.StatusFound, "/login?error=DEPRECATED_LOGIN_METHOD")
}

// HandleLogout 处理登出请求
func (h *WebAuthHandler) HandleLogout(c *gin.Context) {
	cookie := middleware.ExtractTokenFromCookie(c)

	if cookie != "" {
		// 尝试获取 Token 信息用于日志
		authToken, err := h.securityService.AuthenticateToken(cookie)
		if err == nil {
			h.logger.WithFields(logrus.Fields{
				"token_id":  authToken.ID,
				"client_ip": c.ClientIP(),
			}).Info("User logged out")
		} else {
			h.logger.WithField("client_ip", c.ClientIP()).Warn("Logout with invalid token")
		}

		// 使缓存失效
		middleware.InvalidateTokenCache(cookie)
	} else {
		h.logger.WithField("client_ip", c.ClientIP()).Debug("Logout without session cookie")
	}

	// 清除 Cookie
	middleware.ClearAdminSessionCookie(c)

	// 重定向到登录页
	c.Redirect(http.StatusFound, "/login")
}

// validateRedirectPath 验证重定向路径（防止开放重定向攻击）
func (h *WebAuthHandler) validateRedirectPath(path string) string {
	defaultPath := "/dashboard"

	if path == "" {
		return defaultPath
	}

	// 只允许内部路径
	if !strings.HasPrefix(path, "/") || strings.HasPrefix(path, "//") {
		h.logger.WithField("path", path).Warn("Invalid redirect path blocked")
		return defaultPath
	}

	// 白名单验证
	allowedPaths := []string{
		"/dashboard",
		"/keys",
		"/settings",
		"/logs",
		"/tasks",
		"/chat",
	}

	for _, allowed := range allowedPaths {
		if strings.HasPrefix(path, allowed) {
			return path
		}
	}

	return defaultPath
}
