package handler

import (
	"crypto/subtle"

	"github.com/gin-gonic/gin"
	// removed router import
	"github.com/gotunnel/internal/server/router/dto"
	"github.com/gotunnel/pkg/auth"
	"github.com/gotunnel/pkg/security"
)

// AuthHandler 认证处理器
type AuthHandler struct {
	username string
	password string
	jwtAuth  *auth.JWTAuth
}

// NewAuthHandler 创建认证处理器
func NewAuthHandler(username, password string, jwtAuth *auth.JWTAuth) *AuthHandler {
	return &AuthHandler{
		username: username,
		password: password,
		jwtAuth:  jwtAuth,
	}
}

// Login 用户登录
// @Summary 用户登录
// @Description 使用用户名密码登录，返回 JWT token
// @Tags 认证
// @Accept json
// @Produce json
// @Param request body dto.LoginRequest true "登录信息"
// @Success 200 {object} Response{data=dto.LoginResponse}
// @Failure 400 {object} Response
// @Failure 401 {object} Response
// @Router /api/auth/login [post]
func (h *AuthHandler) Login(c *gin.Context) {
	var req dto.LoginRequest
	if !BindJSON(c, &req) {
		return
	}

	// 验证用户名密码 (使用常量时间比较防止时序攻击)
	userMatch := subtle.ConstantTimeCompare([]byte(req.Username), []byte(h.username)) == 1
	passMatch := subtle.ConstantTimeCompare([]byte(req.Password), []byte(h.password)) == 1

	if !userMatch || !passMatch {
		security.LogWebLogin(c.ClientIP(), req.Username, false)
		Unauthorized(c, "invalid credentials")
		return
	}

	// 生成 token
	token, err := h.jwtAuth.GenerateToken(req.Username)
	if err != nil {
		InternalError(c, "failed to generate token")
		return
	}

	security.LogWebLogin(c.ClientIP(), req.Username, true)
	Success(c, dto.LoginResponse{Token: token})
}

// Check 检查 token 是否有效
// @Summary 检查 Token
// @Description 验证 JWT token 是否有效
// @Tags 认证
// @Produce json
// @Security Bearer
// @Success 200 {object} Response{data=dto.TokenCheckResponse}
// @Failure 401 {object} Response
// @Router /api/auth/check [get]
func (h *AuthHandler) Check(c *gin.Context) {
	authHeader := c.GetHeader("Authorization")
	if authHeader == "" {
		Unauthorized(c, "missing authorization header")
		return
	}

	const prefix = "Bearer "
	if len(authHeader) < len(prefix) || authHeader[:len(prefix)] != prefix {
		Unauthorized(c, "invalid authorization format")
		return
	}
	tokenStr := authHeader[len(prefix):]

	claims, err := h.jwtAuth.ValidateToken(tokenStr)
	if err != nil {
		Unauthorized(c, "invalid token")
		return
	}

	Success(c, dto.TokenCheckResponse{
		Valid:    true,
		Username: claims.Username,
	})
}
