package backend

import (
	"bwallet/pkg/encrypt"
	"bwallet/pkg/errno"
	"bwallet/pkg/handler"
	"bwallet/pkg/util"
	"bwallet/service/manager_service"
	"bwallet/validate_service"
	"github.com/Unknwon/com"
	"github.com/astaxie/beego/validation"
	"github.com/gin-gonic/gin"
	"strings"
)

func AddManager(c *gin.Context) {
	manager := validate_service.Manager{}
	c.ShouldBindJSON(&manager)

	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	var group string
	var platform_id int32

	if ("administrator" == user.UserInfo.Group) {
		group = "admin"
		platform_id = manager.PlatformId
	}

	if ("admin" == user.UserInfo.Group) {
		group = "general"
		platform_id = int32(user.UserInfo.PlatformId)
	}

	if ok, errors := validate_service.ValidateInputs(manager); !ok {
		for _, err := range errors {
			handler.SendResponse(c, errno.ErrBind, strings.Join(err, " "))
			return
		}
	}
	manager_service := manager_service.Manager{}
	manager_service.UserName = manager.UserName
	count, err := manager_service.Count()
	if count > 0 || err != nil {
		handler.SendResponse(c, errno.ErrExistUser, nil)
		return
	}

	reg_ip := c.ClientIP()
	ip, _ := util.IPString2Long(reg_ip)
	password, _ := encrypt.HashPassword(manager.Password)

	manager_service.Password = password
	manager_service.RegIp = uint32(ip)
	manager_service.Group = group
	manager_service.PlatformId = platform_id

	if err := manager_service.Add(); err != nil {
		handler.SendResponse(c, errno.ErrAddUser, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}

func GetManagers(c *gin.Context) {
	username := ""
	if arg := c.Query("username"); arg != "" {
		username = c.Query("username")
	}

	var status uint8
	if arg := c.Query("status"); arg != "" {
		status = com.StrTo(c.DefaultQuery("status", "0")).MustUint8()
	}

	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)

	var platform_id int32
	platform_id = int32(user.UserInfo.PlatformId)

	if ("general" == user.UserInfo.Group) {
		handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
		return
	}

	if ("administrator" == user.UserInfo.Group) {
		platform_id = int32(com.StrTo(c.DefaultQuery("platform_id", "0")).MustInt())
	}
	manager_service := manager_service.Manager{
		UserName:   username,
		Status:     status,
		Uid:        int32(user.UserInfo.Uid),
		PlatformId: platform_id,
		PageNum:    util.GetPage(c),
		PageSize:   util.GetLimit(c),
	}

	total, err := manager_service.Count()
	if err != nil {
		handler.SendResponse(c, errno.ErrCountUsers, nil)
		return
	}

	managers, err := manager_service.GetAll()
	if err != nil {
		handler.SendResponse(c, errno.InternalServerError, nil)
		return
	}

	data := make(map[string]interface{})
	data["items"] = managers
	data["total"] = total

	handler.SendResponse(c, nil, data)
}

func EditManager(c *gin.Context) {
	manager_params := validate_service.EditManager{}
	c.ShouldBindJSON(&manager_params)

	if ok, errors := validate_service.ValidateInputs(manager_params); !ok {
		for _, err := range errors {
			handler.SendResponse(c, errno.ErrBind, strings.Join(err, " "))
			return
		}
	}
	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	group := user.UserInfo.Group

	if int32(user.UserInfo.Uid) == manager_params.Uid {
		handler.SendResponse(c, errno.ErrDeleteSelf, nil)
		return
	}

	if ("general" == group) {
		handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
		return
	}

	manager_service := manager_service.Manager{Uid: manager_params.Uid}
	manager, err := manager_service.GetManager()
	if err != nil {
		handler.SendResponse(c, errno.ErrValidation, nil)
		return
	}

	var platform_id int32
	platform_id = int32(user.UserInfo.PlatformId)

	if user.UserInfo.Group == manager.Group {
		handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
		return
	}

	if "admin" == group && platform_id != manager.PlatformId {
		handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
		return
	}

	if "administrator" == manager.Group {
		handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
		return
	}

	manager_service.Status = manager_params.Status
	err = manager_service.Edit()
	if err != nil {
		handler.SendResponse(c, errno.ErrUpdateSelf, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}

func DeleteManager(c *gin.Context) {
	id := int32(com.StrTo(c.DefaultQuery("uid", "0")).MustInt())
	valid := validation.Validation{}
	valid.Min(id, 1, "id").Message("ID必须大于0")
	if valid.HasErrors() {
		handler.SendResponse(c, errno.ErrValidation, nil)
		return
	}

	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	group := user.UserInfo.Group

	if int32(user.UserInfo.Uid) == id {
		handler.SendResponse(c, errno.ErrDeleteSelf, nil)
		return
	}

	if ("general" == group) {
		handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
		return
	}

	manager_service := manager_service.Manager{Uid: id}
	manager, err := manager_service.GetManager()
	if err != nil {
		handler.SendResponse(c, errno.ErrValidation, nil)
		return
	}

	var platform_id int32
	platform_id = int32(user.UserInfo.PlatformId)

	if "administrator" == manager.Group {
		handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
		return
	}

	if "admin" == group && platform_id != manager.PlatformId {
		handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
		return
	}

	err = manager_service.Delete()
	if err != nil {
		handler.SendResponse(c, errno.ErrDeleteUser, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}
