package backend

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

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

	description := ""
	if arg := c.Query("description"); arg != "" {
		description = c.Query("description")
	}

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

	group := user.UserInfo.Group
	platform_id := user.UserInfo.PlatformId
	roleService := casbin_service.Role{}
	if ("administrator" == group) {
		if arg := c.Query("platform_id"); arg != "" {
			platform_id = com.StrTo(c.Query("platform_id")).MustInt()
		}
	}

	roleService = casbin_service.Role{
		RoleName:    role_name,
		Description: description,
		PlatformId:  int32(platform_id),
	}

	roles, err := roleService.GetAllRoles()
	if err != nil {
		handler.SendResponse(c, errno.InternalServerError, nil)
		return
	}

	handler.SendResponse(c, nil, roles)
}

func AddRole(c *gin.Context) {
	role := validate_service.Role{}
	c.ShouldBindJSON(&role)

	if ok, errors := validate_service.ValidateInputs(role); !ok {
		for _, err := range errors {
			handler.SendResponse(c, errno.ErrBind, strings.Join(err, " "))
			return
		}
	}

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

	roleService := casbin_service.Role{
		RoleName:    role.RoleName,
		Description: role.Description,
		PlatformId:  platform_id,
	}

	if err := roleService.AddRole(); err != nil {
		handler.SendResponse(c, errno.ErrAddRole, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}

func EditRole(c *gin.Context) {
	role_tmp := validate_service.EditRole{}
	c.ShouldBindJSON(&role_tmp)

	if ok, errors := validate_service.ValidateInputs(role_tmp); !ok {
		for _, err := range errors {
			handler.SendResponse(c, errno.ErrBind, strings.Join(err, " "))
			return
		}
	}

	roleService := casbin_service.Role{Id: role_tmp.Id}
	role, err := roleService.GetRole()
	if err != nil {
		handler.SendResponse(c, errno.ErrRoleNotFound, nil)
		return
	}
	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	platform_id := int64(user.UserInfo.PlatformId)
	if platform_id != role.PlatformId {
		handler.SendResponse(c, errno.ErrUpdateRole, nil)
		return
	}
	roleService = casbin_service.Role{
		Id:          role_tmp.Id,
		RoleName:    role_tmp.RoleName,
		Description: role_tmp.Description,
	}
	if err := roleService.EditRole(); err != nil {
		handler.SendResponse(c, errno.ErrUpdateRole, nil)
		return
	}
	handler.SendResponse(c, nil, nil)
}

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

	roleService := casbin_service.Role{Id: int32(id)}
	role, err := roleService.GetRole()

	if err != nil {
		handler.SendResponse(c, errno.ErrRoleNotFound, nil)
		return
	}
	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	platform_id := int64(user.UserInfo.PlatformId)
	if platform_id != role.PlatformId {
		handler.SendResponse(c, errno.ErrUpdateRole, nil)
		return
	}

	roleRelatedService := casbin_service.AdminRole{
		RoleId:   int32(id),
		PageNum:  util.GetPage(c),
		PageSize: util.GetLimit(c),
	}
	roleRelatedInfo, err := roleRelatedService.GetAllAdminRoles()
	if err != nil {
		handler.SendResponse(c, errno.ErrRoleNotFound, nil)
		return
	}
	if len(roleRelatedInfo) > 0 {
		handler.SendResponse(c, errno.ErrRoleAdminExits, nil)
		return
	}

	err = roleService.DeleteRole()
	if err != nil {
		handler.SendResponse(c, errno.ErrDeleteWallet, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}
