package api

import (
	"encoding/base64"
	"errors"
	"fmt"
	"gitee.ltd/lxh/logger/log"
	"github.com/gin-gonic/gin"
	"strings"
	"wireguard-ui/global/constant"
	"wireguard-ui/http/param"
	"wireguard-ui/http/response"
	"wireguard-ui/model"
	"wireguard-ui/service"
	"wireguard-ui/utils"
)

type UserApi struct{}

func User() UserApi {
	return UserApi{}
}

// GetLoginUser
// @description: 获取登陆用户信息
// @receiver UserApi
// @param c
func (UserApi) GetLoginUser(c *gin.Context) {
	loginUser, ok := c.Get("user")
	if !ok {
		response.R(c).AuthorizationFailed("未登陆")
		return
	}

	response.R(c).OkWithData(loginUser)
}

// SaveUser
// @description: 新增/编辑用户信息
// @receiver UserApi
// @param c
func (UserApi) SaveUser(c *gin.Context) {
	var p param.SaveUser
	if err := c.ShouldBind(&p); err != nil {
		response.R(c).Validator(err)
		return
	}

	// 如果是新增用户判断该用户是否已经存在
	if p.Id == "" {
		if len(p.Account) < 2 || len(p.Account) > 20 {
			response.R(c).FailedWithError(errors.New("账号长度在2-20位"))
			return
		}
		if (len(p.Password) < 8 || len(p.Password) > 32) && p.Password != "" {
			response.R(c).FailedWithError(errors.New("密码长度在8-32位"))
			return
		}

		var count int64
		if err := service.User().Model(&model.User{}).Where("account = ?", p.Account).Count(&count).Error; err != nil {
			response.R(c).FailedWithError(err)
			return
		}

		if count > 0 {
			response.R(c).FailedWithError(errors.New("该账号已存在"))
			return
		}
	}

	if strings.HasPrefix(p.Avatar, "data:image/png;base64,") {
		avatar := strings.Replace(p.Avatar, "data:image/png;base64,", "", -1)
		avatarByte, err := base64.StdEncoding.DecodeString(avatar)
		if err != nil {
			log.Errorf("反解析头像失败: %v", err.Error())
			response.R(c).FailedWithError("上传头像失败")
			return
		}

		file, err := utils.FileSystem().UploadFile(avatarByte, ".png")
		if err != nil {
			log.Errorf("上传头像失败: %v", err.Error())
			response.R(c).FailedWithError("上传头像失败")
			return
		}

		p.Avatar = file
	}

	userEnt := &model.User{
		Base: model.Base{
			Id: p.Id,
		},
		Account:  p.Account,
		Password: p.Password,
		Nickname: p.Nickname,
		Avatar:   p.Avatar,
		Contact:  p.Contact,
		IsAdmin:  *p.IsAdmin,
		Status:   *p.Status,
	}

	if err := service.User().CreateUser(userEnt); err != nil {
		response.R(c).FailedWithError(err)
		return
	}

	response.R(c).OK()
}

// List
// @description: 用户列表
// @receiver UserApi
// @param c
func (UserApi) List(c *gin.Context) {
	var p param.Page
	if err := c.ShouldBind(&p); err != nil {
		response.R(c).Validator(err)
		return
	}

	data, total, err := service.User().List(p)
	if err != nil {
		response.R(c).FailedWithError(err)
		return
	}

	response.R(c).Paginate(data, total, p.Current, p.Size)
}

// Delete
// @description: 删除用户
// @receiver UserApi
// @param c
func (UserApi) Delete(c *gin.Context) {
	id := c.Param("id")
	if id == "" || id == "undefined" {
		response.R(c).FailedWithError("id不能为空")
		return
	}

	// 是不是自己删除自己
	if id == GetCurrentLoginUser(c).Id && c.IsAborted() {
		response.R(c).FailedWithError("非法操作")
		return
	}

	// 先查询一下
	user, err := service.User().GetUserById(id)
	if err != nil {
		response.R(c).FailedWithError("获取用户信息失败")
		return
	}

	// admin用户不能被删除
	if user.Account == "admin" {
		response.R(c).FailedWithError("当前用户不能被删除")
		return
	}

	if err = service.User().Delete(id); err != nil {
		response.R(c).FailedWithError("删除用户失败")
		return
	}

	response.R(c).OK()
}

// Status
// @description: 设置用户状态
// @receiver UserApi
// @param c
func (UserApi) Status(c *gin.Context) {
	id := c.Param("id")
	if id == "" || id == "undefined" {
		response.R(c).FailedWithError("id不能为空")
		return
	}

	// 是不是自己删除自己
	if id == GetCurrentLoginUser(c).Id && c.IsAborted() {
		response.R(c).FailedWithError("非法操作")
		return
	}

	// 先查询一下
	user, err := service.User().GetUserById(id)
	if err != nil {
		response.R(c).FailedWithError("获取用户信息失败")
		return
	}

	// admin用户不能被删除
	if user.Account == "admin" {
		response.R(c).FailedWithError("当前用户状态不可被变更")
		return
	}

	var state = constant.Enabled
	if user.Status == constant.Enabled {
		state = constant.Disabled
	}

	if err := service.User().Status(id, state); err != nil {
		response.R(c).FailedWithError(err)
		return
	}

	response.R(c).OK()
}

// ChangePassword
// @description: 修改密码
// @receiver UserApi
// @param c
func (UserApi) ChangePassword(c *gin.Context) {
	var p param.ChangePassword
	if err := c.ShouldBind(&p); err != nil {
		response.R(c).Validator(err)
		return
	}

	user := GetCurrentLoginUser(c)
	if user == nil {
		response.R(c).FailedWithError("用户信息错误")
		return
	}

	// 判断原密码是否对
	if !utils.Password().ComparePassword(user.Password, p.OriginalPassword) {
		response.R(c).FailedWithError("原密码错误")
		return
	}

	// 修改密码
	if err := service.User().ChangePassword(user.Id, p.NewPassword); err != nil {
		response.R(c).FailedWithError(err)
		return
	}

	response.R(c).OK()
}

// ResetPassword
// @description: 重置密码
// @receiver UserApi
// @param c
func (UserApi) ResetPassword(c *gin.Context) {
	var id = c.Param("id")
	if id == "" || id == "undefined" {
		response.R(c).FailedWithError("id不能为空")
		return
	}

	// 先查询一下
	user, err := service.User().GetUserById(id)
	if err != nil {
		response.R(c).FailedWithError("获取用户信息失败")
		return
	}

	if user.Status != constant.Enabled {
		response.R(c).FailedWithError("当前用户不可重置密码")
		return
	}

	// 修改密码
	if err := service.User().ChangePassword(user.Id, "admin123"); err != nil {
		response.R(c).FailedWithError(err)
		return
	}

	response.R(c).OK()
}

// GenerateAvatar
// @description: 生成头像
// @receiver UserApi
// @param c
func (UserApi) GenerateAvatar(c *gin.Context) {
	avatar, err := utils.Avatar().GenerateAvatar(false)
	if err != nil {
		response.R(c).FailedWithError(fmt.Errorf("生成头像失败: %s", err.Error()))
		return
	}

	response.R(c).OkWithData(fmt.Sprintf("data:image/png;base64,%s", base64.StdEncoding.EncodeToString([]byte(avatar))))
}