package system

import (
	"encoding/json"
	"strconv"
	"time"

	"kra/internal/biz/system"
	"kra/pkg/response"
	"kra/pkg/utils"

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

type UserApi struct{}

// RegisterRequest 注册请求
type RegisterRequest struct {
	Username     string `json:"userName" binding:"required"`
	Password     string `json:"password" binding:"required"`
	NickName     string `json:"nickName"`
	HeaderImg    string `json:"headerImg"`
	AuthorityId  uint   `json:"authorityId" binding:"required"`
	AuthorityIds []uint `json:"authorityIds"`
	Phone        string `json:"phone"`
	Email        string `json:"email"`
	Enable       int    `json:"enable"`
}

// ChangePasswordRequest 修改密码请求
type ChangePasswordRequest struct {
	Password    string `json:"password" binding:"required"`
	NewPassword string `json:"newPassword" binding:"required"`
}

// ResetPasswordRequest 重置密码请求
type ResetPasswordRequest struct {
	ID       uint   `json:"ID" binding:"required"`
	Password string `json:"password"`
}

// GetUserListRequest 获取用户列表请求
type GetUserListRequest struct {
	Page     int    `json:"page"`
	PageSize int    `json:"pageSize"`
	Username string `json:"username"`
	NickName string `json:"nickName"`
	Phone    string `json:"phone"`
	Email    string `json:"email"`
}

// SetUserInfoRequest 设置用户信息请求
type SetUserInfoRequest struct {
	ID           uint   `json:"ID" binding:"required"`
	NickName     string `json:"nickName"`
	HeaderImg    string `json:"headerImg"`
	Phone        string `json:"phone"`
	Email        string `json:"email"`
	Enable       int    `json:"enable"`
	AuthorityIds []uint `json:"authorityIds"`
}

// SetSelfInfoRequest 设置自己信息请求
type SetSelfInfoRequest struct {
	NickName  string `json:"nickName"`
	HeaderImg string `json:"headerImg"`
	Phone     string `json:"phone"`
	Email     string `json:"email"`
}

// SetUserAuthorityRequest 设置用户角色请求
type SetUserAuthorityRequest struct {
	AuthorityId uint `json:"authorityId" binding:"required"`
}

// SetUserAuthoritiesRequest 设置用户多角色请求
type SetUserAuthoritiesRequest struct {
	ID           uint   `json:"ID" binding:"required"`
	AuthorityIds []uint `json:"authorityIds" binding:"required"`
}

// DeleteUserRequest 删除用户请求
type DeleteUserRequest struct {
	ID uint `json:"ID" binding:"required"`
}

// Register
// @Tags      SysUser
// @Summary   用户注册账号
// @Produce   application/json
// @Param     data  body      RegisterRequest                                            true  "用户名, 昵称, 密码, 角色ID"
// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "用户注册账号,返回包括用户信息"
// @Router    /user/admin_register [post]
func (u *UserApi) Register(c *gin.Context) {
	var req RegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	user := &system.User{
		Username:    req.Username,
		Password:    req.Password,
		NickName:    req.NickName,
		HeaderImg:   req.HeaderImg,
		AuthorityId: req.AuthorityId,
		Phone:       req.Phone,
		Email:       req.Email,
		Enable:      req.Enable,
	}

	created, err := userUsecase.Register(c, user)
	if err != nil {
		response.FailWithDetailed(gin.H{"user": created}, "注册失败", c)
		return
	}

	response.OkWithDetailed(gin.H{"user": toUserResponse(created)}, "注册成功", c)
}

// ChangePassword
// @Tags      SysUser
// @Summary   用户修改密码
// @Security  ApiKeyAuth
// @Produce   application/json
// @Param     data  body      ChangePasswordRequest          true  "用户名, 原密码, 新密码"
// @Success   200   {object}  response.Response{msg=string}  "用户修改密码"
// @Router    /user/changePassword [post]
func (u *UserApi) ChangePassword(c *gin.Context) {
	var req ChangePasswordRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	userID := utils.GetUserID(c)
	if userID == 0 {
		response.FailWithMessage("请先登录", c)
		return
	}

	if err := userUsecase.ChangePassword(c, userID, req.Password, req.NewPassword); err != nil {
		response.FailWithMessage("修改失败，原密码与当前账户不符", c)
		return
	}

	response.OkWithMessage("修改成功", c)
}

// ResetPassword
// @Tags      SysUser
// @Summary   重置用户密码
// @Security  ApiKeyAuth
// @Produce   application/json
// @Param     data  body      ResetPasswordRequest           true  "ID"
// @Success   200   {object}  response.Response{msg=string}  "重置用户密码"
// @Router    /user/resetPassword [post]
func (u *UserApi) ResetPassword(c *gin.Context) {
	var req ResetPasswordRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	if err := userUsecase.ResetPassword(c, req.ID, req.Password); err != nil {
		response.FailWithMessage("重置失败"+err.Error(), c)
		return
	}

	response.OkWithMessage("重置成功", c)
}

// GetUserInfo
// @Tags      SysUser
// @Summary   获取用户信息
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Success   200  {object}  response.Response{data=map[string]interface{},msg=string}  "获取用户信息"
// @Router    /user/getUserInfo [get]
func (u *UserApi) GetUserInfo(c *gin.Context) {
	uuid := utils.GetUserUuid(c)
	user, err := userUsecase.GetUserInfo(c, uuid.String())
	if err != nil {
		response.FailWithMessage("获取失败", c)
		return
	}

	// 检查用户角色默认路由
	if user.Authority != nil {
		defaultRouter := menuUsecase.UserAuthorityDefaultRouter(c, user.AuthorityId, user.Authority.DefaultRouter)
		user.Authority.DefaultRouter = defaultRouter
	}

	response.OkWithDetailed(gin.H{"userInfo": toUserResponse(user)}, "获取成功", c)
}

// GetUserList
// @Tags      SysUser
// @Summary   分页获取用户列表
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      GetUserListRequest                                       true  "页码, 每页大小"
// @Success   200   {object}  response.Response{data=response.PageResult,msg=string}  "分页获取用户列表,返回包括列表,总数,页码,每页数量"
// @Router    /user/getUserList [post]
func (u *UserApi) GetUserList(c *gin.Context) {
	var req GetUserListRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	if req.Page == 0 {
		req.Page = 1
	}
	if req.PageSize == 0 {
		req.PageSize = 10
	}

	filters := make(map[string]string)
	if req.Username != "" {
		filters["username"] = req.Username
	}
	if req.NickName != "" {
		filters["nick_name"] = req.NickName
	}
	if req.Phone != "" {
		filters["phone"] = req.Phone
	}
	if req.Email != "" {
		filters["email"] = req.Email
	}

	users, total, err := userUsecase.GetUserList(c, req.Page, req.PageSize, filters)
	if err != nil {
		response.FailWithMessage("获取失败", c)
		return
	}

	list := make([]interface{}, len(users))
	for i, u := range users {
		list[i] = toUserResponse(u)
	}

	response.OkWithDetailed(response.PageResult{
		List:     list,
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	}, "获取成功", c)
}

// SetUserInfo
// @Tags      SysUser
// @Summary   设置用户信息
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      SetUserInfoRequest                                         true  "ID, 用户名, 昵称, 头像链接"
// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "设置用户信息"
// @Router    /user/setUserInfo [put]
func (u *UserApi) SetUserInfo(c *gin.Context) {
	var req SetUserInfoRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 设置用户角色
	if len(req.AuthorityIds) > 0 {
		authorityID := utils.GetUserAuthorityId(c)
		if err := userUsecase.SetUserAuthorities(c, authorityID, req.ID, req.AuthorityIds); err != nil {
			response.FailWithMessage("设置失败", c)
			return
		}
	}

	user := &system.User{
		ID:        req.ID,
		NickName:  req.NickName,
		HeaderImg: req.HeaderImg,
		Phone:     req.Phone,
		Email:     req.Email,
		Enable:    req.Enable,
	}

	if err := userUsecase.SetUserInfo(c, user); err != nil {
		response.FailWithMessage("设置失败", c)
		return
	}

	response.OkWithMessage("设置成功", c)
}

// SetSelfInfo
// @Tags      SysUser
// @Summary   设置用户信息
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      SetSelfInfoRequest                                         true  "ID, 用户名, 昵称, 头像链接"
// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "设置用户信息"
// @Router    /user/SetSelfInfo [put]
func (u *UserApi) SetSelfInfo(c *gin.Context) {
	var req SetSelfInfoRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	userID := utils.GetUserID(c)
	if userID == 0 {
		response.FailWithMessage("请先登录", c)
		return
	}

	user := &system.User{
		ID:        userID,
		NickName:  req.NickName,
		HeaderImg: req.HeaderImg,
		Phone:     req.Phone,
		Email:     req.Email,
	}

	if err := userUsecase.SetSelfInfo(c, user); err != nil {
		response.FailWithMessage("设置失败", c)
		return
	}

	response.OkWithMessage("设置成功", c)
}

// SetSelfSetting
// @Tags      SysUser
// @Summary   设置用户配置
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      map[string]interface{}  true  "用户配置数据"
// @Success   200   {object}  response.Response{data=map[string]interface{},msg=string}  "设置用户配置"
// @Router    /user/SetSelfSetting [put]
func (u *UserApi) SetSelfSetting(c *gin.Context) {
	var req map[string]interface{}
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	userID := utils.GetUserID(c)
	if userID == 0 {
		response.FailWithMessage("请先登录", c)
		return
	}

	setting, _ := json.Marshal(req)
	if err := userUsecase.SetSelfSetting(c, userID, setting); err != nil {
		response.FailWithMessage("设置失败", c)
		return
	}

	response.OkWithMessage("设置成功", c)
}

// DeleteUser
// @Tags      SysUser
// @Summary   删除用户
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      DeleteUserRequest              true  "用户ID"
// @Success   200   {object}  response.Response{msg=string}  "删除用户"
// @Router    /user/deleteUser [delete]
func (u *UserApi) DeleteUser(c *gin.Context) {
	var req DeleteUserRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	currentUserID := utils.GetUserID(c)
	if currentUserID == req.ID {
		response.FailWithMessage("删除失败, 无法删除自己。", c)
		return
	}

	if err := userUsecase.DeleteUser(c, req.ID); err != nil {
		response.FailWithMessage("删除失败", c)
		return
	}

	response.OkWithMessage("删除成功", c)
}

// SetUserAuthority
// @Tags      SysUser
// @Summary   更改用户权限
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      SetUserAuthorityRequest        true  "用户UUID, 角色ID"
// @Success   200   {object}  response.Response{msg=string}  "设置用户权限"
// @Router    /user/setUserAuthority [post]
func (u *UserApi) SetUserAuthority(c *gin.Context) {
	var req SetUserAuthorityRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	userID := utils.GetUserID(c)
	if userID == 0 {
		response.FailWithMessage("请先登录", c)
		return
	}

	if err := userUsecase.SetUserAuthority(c, userID, req.AuthorityId); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 重新生成token
	claims := utils.GetUserInfo(c)
	if claims == nil {
		response.FailWithMessage("请先登录", c)
		return
	}

	claims.AuthorityID = req.AuthorityId
	token, err := jwtInstance.CreateToken(claims.BaseClaims)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	c.Header("new-token", token)
	c.Header("new-expires-at", strconv.FormatInt(claims.ExpiresAt.Unix(), 10))
	utils.SetToken(c, token, int(claims.ExpiresAt.Unix()-time.Now().Unix()))

	response.OkWithMessage("修改成功", c)
}

// SetUserAuthorities
// @Tags      SysUser
// @Summary   设置用户权限
// @Security  ApiKeyAuth
// @accept    application/json
// @Produce   application/json
// @Param     data  body      SetUserAuthoritiesRequest      true  "用户UUID, 角色ID"
// @Success   200   {object}  response.Response{msg=string}  "设置用户权限"
// @Router    /user/setUserAuthorities [post]
func (u *UserApi) SetUserAuthorities(c *gin.Context) {
	var req SetUserAuthoritiesRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	authorityID := utils.GetUserAuthorityId(c)
	if err := userUsecase.SetUserAuthorities(c, authorityID, req.ID, req.AuthorityIds); err != nil {
		response.FailWithMessage("修改失败", c)
		return
	}

	response.OkWithMessage("修改成功", c)
}

// toUserResponse 转换用户响应
func toUserResponse(user *system.User) map[string]interface{} {
	if user == nil {
		return nil
	}

	result := map[string]interface{}{
		"ID":          user.ID,
		"uuid":        user.UUID.String(),
		"userName":    user.Username,
		"nickName":    user.NickName,
		"sideMode":    user.SideMode,
		"headerImg":   user.HeaderImg,
		"baseColor":   user.BaseColor,
		"authorityId": user.AuthorityId,
		"phone":       user.Phone,
		"email":       user.Email,
		"enable":      user.Enable,
	}

	if user.OriginSetting != nil {
		result["originSetting"] = string(user.OriginSetting)
	}

	if user.Authority != nil {
		result["authority"] = map[string]interface{}{
			"authorityId":   user.Authority.AuthorityId,
			"authorityName": user.Authority.AuthorityName,
			"parentId":      user.Authority.ParentId,
			"defaultRouter": user.Authority.DefaultRouter,
		}
	}

	if len(user.Authorities) > 0 {
		authorities := make([]map[string]interface{}, len(user.Authorities))
		for i, a := range user.Authorities {
			authorities[i] = map[string]interface{}{
				"authorityId":   a.AuthorityId,
				"authorityName": a.AuthorityName,
				"parentId":      a.ParentId,
				"defaultRouter": a.DefaultRouter,
			}
		}
		result["authorities"] = authorities
	}

	return result
}
