package casbin

import (
	"github.com/gofiber/fiber/v2"
	"gofiber.study.skcks.cn/common/errorx"
	"gofiber.study.skcks.cn/common/response"
	"gofiber.study.skcks.cn/controller/types"
	"gofiber.study.skcks.cn/global"
)

type Controller struct {
	*types.Controller
}

func (c *Controller) GetRouter() fiber.Router {
	return c.Router
}

func NewController(app *fiber.App) *Controller {
	return &Controller{
		Controller: types.NewController(app, "/casbin"),
	}
}

// TestCasbin casbin 鉴权测试
//
// @Summary      casbin 鉴权测试
// @Description  casbin 鉴权测试
// @Tags         CasBin
// @Accept       json
// @Produce      json
// @Param        identity    query    string true  "身份"
// @Param        system      query    string true  "系统"
// @Param        api         query    string true  "api"
// @Param        act         query    string true  "动作"
// @Success      200  {object}  response.Response{data=string}
// @Failure	     default {object}  errorx.CodeErrorResponse
// @Router       /casbin/test [get]
func (c *Controller) TestCasbin() {
	c.Router.Get("/test", func(ctx *fiber.Ctx) error {
		var identity, system, api, act string

		identity = ctx.Query("identity")
		system = ctx.Query("system")
		api = ctx.Query("api")
		act = ctx.Query("act")

		enforce, err := global.Enforcer.Enforce(identity, system, api, act)
		if err != nil {
			return ctx.JSON(errorx.NewDefaultError(err.Error()))
		}

		if !enforce {
			return ctx.JSON(errorx.NewErrorWithCode(fiber.StatusForbidden, "无权访问"))
		}

		return ctx.JSON(response.NewResponse("授权访问"))
	})
}

// ReloadCasbin 重新加载 casbin 策略
//
// @Summary      重新加载 casbin 策略
// @Description  重新加载 casbin 策略
// @Tags         CasBin
// @Accept       json
// @Produce      json
// @Success      200  {object}  response.Response{data=string}
// @Failure	     default {object}  errorx.CodeErrorResponse
// @Router       /casbin/reload [post]
func (c *Controller) ReloadCasbin() {
	c.Router.Post("/reload", func(ctx *fiber.Ctx) error {
		err := global.Enforcer.LoadPolicy()
		if err != nil {
			return ctx.JSON(errorx.NewErrorWithCode(fiber.StatusForbidden, err.Error()))
		}

		return ctx.JSON(response.NewResponse("重载成功"))
	})
}

type GetUserRolesQuery struct {
	Account string `json:"account" example:"root"`
}

// GetUserRoles 用户所有角色
//
// @Summary      用户所有角色
// @Description  用户所有角色
// @Tags         CasBin
// @Accept       json
// @Produce      json
// @Param		 account query string true "用户账号" default(root)
// @Success      200  {object}  response.Response{data=[]string}
// @Failure	     default {object}  errorx.CodeErrorResponse
// @Router       /casbin/getUserRoles [get]
func (c *Controller) GetUserRoles() {
	c.Router.Get("/getUserRoles", func(ctx *fiber.Ctx) error {
		query := &GetUserRolesQuery{}
		err := ctx.QueryParser(query)
		roles, err := global.Enforcer.GetRolesForUser("user::" + query.Account)
		if err != nil {
			if err != nil {
				return ctx.JSON(errorx.NewErrorWithCode(fiber.StatusForbidden, err.Error()))
			}
		}

		return ctx.JSON(response.NewResponse(roles))
	})
}
