package handlers

import (
	"net/http"

	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/common"
	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/middleware"
	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/models"
	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/services"
	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/utils"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
)

type AuthHandler struct {
	userService *services.UserService
	validator   *validator.Validate
}

func NewAuthHandler(userService *services.UserService) *AuthHandler {
	return &AuthHandler{
		userService: userService,
		validator:   validator.New(),
	}
}

// RegisterRequest 注册请求结构
type RegisterRequest struct {
	Username string `json:"username" validate:"required,min=3,max=20"`
	Email    string `json:"email" validate:"required,email"`
	Password string `json:"password" validate:"required,min=6"`
	Nickname string `json:"nickname" validate:"required,min=1,max=50"`
}

// LoginRequest 登录请求结构
type LoginRequest struct {
	Account  string `json:"account" validate:"required"` // 用户名或邮箱
	Password string `json:"password" validate:"required"`
}

// RefreshTokenRequest 刷新令牌请求结构
type RefreshTokenRequest struct {
	RefreshToken string `json:"refresh_token" validate:"required"`
}

// ChangePasswordRequest 修改密码请求结构
type ChangePasswordRequest struct {
	OldPassword string `json:"old_password" validate:"required"`
	NewPassword string `json:"new_password" validate:"required,min=6"`
}

// AuthResponse 认证响应结构
type AuthResponse struct {
	User         *UserInfo `json:"user"`
	AccessToken  string    `json:"access_token"`
	RefreshToken string    `json:"refresh_token"`
	ExpiresIn    int64     `json:"expires_in"`
}

// UserInfo 用户信息结构
type UserInfo struct {
	ID       int64 `json:"id"`
	Username string `json:"username"`
	Email    string `json:"email"`
	Nickname string `json:"nickname"`
	Avatar   string `json:"avatar"`
	Level    string `json:"level"`
	Status   string `json:"status"`
}

// Register 用户注册
func (h *AuthHandler) Register(c *gin.Context) {
	var req RegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ValidationErrorResponse(c, err)
		return
	}

	// 验证请求参数
	if err := h.validator.Struct(&req); err != nil {
		common.ValidationErrorResponse(c, err)
		return
	}

	// 验证邮箱格式
	if !utils.IsValidEmail(req.Email) {
		common.BadRequestResponse(c, "邮箱格式不正确")
		return
	}

	// 验证密码强度
	if !utils.IsStrongPassword(req.Password) {
		common.BadRequestResponse(c, "密码强度不足，至少8位且包含大小写字母、数字和特殊字符")
		return
	}

	// 创建用户
	user, err := h.userService.CreateUser(req.Username, req.Email, req.Password)
	if err != nil {
		if businessErr, ok := err.(*common.BusinessError); ok {
			common.ErrorResponse(c, http.StatusBadRequest, businessErr.Message)
			return
		}
		common.InternalServerErrorResponse(c, "用户创建失败")
		return
	}

	// 生成令牌
	accessToken, refreshToken, err := middleware.GenerateTokens(user.ID, user.Username, user.Email)
	if err != nil {
		common.InternalServerErrorResponse(c, "令牌生成失败")
		return
	}

	// 更新用户登录信息
	h.userService.UpdateLoginInfo(user.ID, utils.GetClientIP(c))

	// 构造响应
	nickname := ""
	if user.Nickname != nil {
		nickname = *user.Nickname
	}
	avatar := ""
	if user.Avatar != nil {
		avatar = *user.Avatar
	}

	userInfo := &UserInfo{
		ID:       user.ID,
		Username: user.Username,
		Email:    user.Email,
		Nickname: nickname,
		Avatar:   avatar,
		Level:    "beginner",
		Status:   user.Status,
	}

	response := &AuthResponse{
		User:         userInfo,
		AccessToken:  accessToken,
		RefreshToken: refreshToken,
		ExpiresIn:    7200, // 2小时
	}

	common.SuccessResponse(c, response)
}

// Login 用户登录
func (h *AuthHandler) Login(c *gin.Context) {
	var req LoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ValidationErrorResponse(c, err)
		return
	}

	// 验证请求参数
	if err := h.validator.Struct(&req); err != nil {
		common.ValidationErrorResponse(c, err)
		return
	}

	// 根据账号类型获取用户
	var user *models.User
	var err error

	if utils.IsValidEmail(req.Account) {
		user, err = h.userService.GetUserByEmail(req.Account)
	} else {
		user, err = h.userService.GetUserByUsername(req.Account)
	}

	if err != nil {
		if businessErr, ok := err.(*common.BusinessError); ok {
			common.ErrorResponse(c, http.StatusBadRequest, businessErr.Message)
			return
		}
		common.InternalServerErrorResponse(c, "用户查询失败")
		return
	}

	// 验证密码
	if !utils.CheckPasswordHash(req.Password, user.PasswordHash) {
		common.BadRequestResponse(c, "密码错误")
		return
	}

	// 检查用户状态
	if user.Status != "active" {
		common.BadRequestResponse(c, "用户已被禁用")
		return
	}

	// 生成令牌
	accessToken, refreshToken, err := middleware.GenerateTokens(user.ID, user.Username, user.Email)
	if err != nil {
		common.InternalServerErrorResponse(c, "令牌生成失败")
		return
	}

	// 更新用户登录信息
	h.userService.UpdateLoginInfo(user.ID, utils.GetClientIP(c))

	// 构造响应
	nickname := ""
	if user.Nickname != nil {
		nickname = *user.Nickname
	}
	avatar := ""
	if user.Avatar != nil {
		avatar = *user.Avatar
	}

	userInfo := &UserInfo{
		ID:       user.ID,
		Username: user.Username,
		Email:    user.Email,
		Nickname: nickname,
		Avatar:   avatar,
		Level:    "beginner",
		Status:   user.Status,
	}

	response := &AuthResponse{
		User:         userInfo,
		AccessToken:  accessToken,
		RefreshToken: refreshToken,
		ExpiresIn:    7200, // 2小时
	}

	common.SuccessResponse(c, response)
}

// RefreshToken 刷新访问令牌
func (h *AuthHandler) RefreshToken(c *gin.Context) {
	var req RefreshTokenRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ValidationErrorResponse(c, err)
		return
	}

	// 验证刷新令牌
	claims, err := middleware.ParseToken(req.RefreshToken)
	if err != nil {
		common.BadRequestResponse(c, "无效的刷新令牌")
		return
	}

	// 检查令牌类型
	if claims.Type != "refresh" {
		common.BadRequestResponse(c, "令牌类型错误")
		return
	}

	// 生成新的令牌
	accessToken, newRefreshToken, err := middleware.GenerateTokens(claims.UserID, claims.Username, claims.Email)
	if err != nil {
		common.InternalServerErrorResponse(c, "令牌生成失败")
		return
	}

	response := map[string]interface{}{
		"access_token":  accessToken,
		"refresh_token": newRefreshToken,
		"expires_in":    7200,
	}

	common.SuccessResponse(c, response)
}

// Logout 用户登出
func (h *AuthHandler) Logout(c *gin.Context) {
	// 这里可以实现令牌黑名单机制
	// 目前简单返回成功
	common.SuccessResponse(c, map[string]string{"message": "登出成功"})
}

// GetProfile 获取用户资料
func (h *AuthHandler) GetProfile(c *gin.Context) {
	// 获取当前用户ID
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		common.BadRequestResponse(c, "请先登录")
		return
	}

	user, err := h.userService.GetUserByID(userID)
	if err != nil {
		if businessErr, ok := err.(*common.BusinessError); ok {
			common.ErrorResponse(c, http.StatusBadRequest, businessErr.Message)
			return
		}
		common.InternalServerErrorResponse(c, "用户查询失败")
		return
	}

	nickname := ""
	if user.Nickname != nil {
		nickname = *user.Nickname
	}
	avatar := ""
	if user.Avatar != nil {
		avatar = *user.Avatar
	}

	userInfo := &UserInfo{
		ID:       user.ID,
		Username: user.Username,
		Email:    user.Email,
		Nickname: nickname,
		Avatar:   avatar,
		Level:    "beginner",
		Status:   user.Status,
	}

	common.SuccessResponse(c, userInfo)
}

// ChangePassword 修改密码
func (h *AuthHandler) ChangePassword(c *gin.Context) {
	// 获取当前用户ID
	userID, exists := utils.GetUserIDFromContext(c)
	if !exists {
		common.BadRequestResponse(c, "请先登录")
		return
	}

	var req ChangePasswordRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		common.ValidationErrorResponse(c, err)
		return
	}

	// 验证请求参数
	if err := h.validator.Struct(&req); err != nil {
		common.ValidationErrorResponse(c, err)
		return
	}

	// 验证新密码强度
	if !utils.IsStrongPassword(req.NewPassword) {
		common.BadRequestResponse(c, "新密码强度不够")
		return
	}

	// 更新密码
	err := h.userService.UpdatePassword(userID, req.OldPassword, req.NewPassword)
	if err != nil {
		if businessErr, ok := err.(*common.BusinessError); ok {
			common.ErrorResponse(c, http.StatusBadRequest, businessErr.Message)
			return
		}
		common.InternalServerErrorResponse(c, "密码更新失败")
		return
	}

	common.SuccessResponse(c, map[string]string{"message": "密码修改成功"})
}