package backend

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

func GetPermissions(c *gin.Context) {
	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	group := user.UserInfo.Group
	if group != "admin" {
		handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
		return
	}

	id := int32(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: id,
	}
	roleInfo, err := roleService.GetRole()
	if err != nil {
		handler.SendResponse(c, errno.ErrRoleNotFound, nil)
		return
	}

	casbin_service := casbin_service.SetPermission{
		Value: roleInfo.RoleName,
	}
	permissions := casbin_service.GetPermissions()

	handler.SendResponse(c, nil, permissions)
}

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

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

	managerService := manager_service.Manager{
		Uid: int32(role.Uid),
	}
	managerInfo, err := managerService.GetManager()
	fmt.Println(managerInfo, managerInfo.Uid, managerInfo.Username)
	if err != nil {
		handler.SendResponse(c, errno.ErrUserNotFound, nil)
		return
	}

	roleService := casbin_service.Role{
		Id: role.RoleId,
	}
	roleInfo, err := roleService.GetRole()
	if err != nil {
		handler.SendResponse(c, errno.ErrRoleNotFound, nil)
		return
	}

	casbinService := casbin_service.AdminRole{
		Uid:    role.Uid,
		RoleId: role.RoleId,
	}

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

	casbin_service := casbin_service.CasbinRole{
		V0: managerInfo.Username,
		V1: roleInfo.RoleName,
	}
	if err := casbin_service.AddGroupingPolicy(); err != nil {
		handler.SendResponse(c, errno.ErrAddRole, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}

func SetRole(c *gin.Context) {
	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	group := user.UserInfo.Group

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

	casbin_service := casbin_service.CasbinRole{
		V0: role.Value,
		V1: role.AllowRole,
	}
	if err := casbin_service.AddGroupingPolicy(); err != nil {
		handler.SendResponse(c, errno.ErrAddCoin, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}

func SetPermission(c *gin.Context) {
	token := c.Request.Header.Get("Token")
	user, _ := util.ParseToken(token)
	group := user.UserInfo.Group
	if group != "admin" {
		handler.SendResponse(c, errno.ErrUserAuthIncorrect, nil)
		return
	}

	var permission casbin_service.SetPermission
	_ = c.ShouldBindJSON(&permission)

	casbin_service := casbin_service.SetPermission{
		Value:            permission.Value,
		AllowPermissions: permission.AllowPermissions,
	}

	if err := casbin_service.AddPolicy(); err != nil {
		handler.SendResponse(c, errno.ErrAddCoin, nil)
		return
	}

	handler.SendResponse(c, nil, nil)
}
