package api

import (
	"net/http"

	rbacsvc "github.com/tidbcloud/account/internel/svc/rbac"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	"github.com/gin-gonic/gin"
	"github.com/tidbcloud/account/admin/forms"
)

// @Summary CreateRbacRolePrivilege
// @tags ManagementPortalUser
// @Accept  json
// @Produce json
// @Param role body forms.GrantRolePrivilege true "CreateRbacRolePrivilege"
// @Success 200 {object} forms.EmptyResponse
// @Router /rbac/role-privilege/create [post]
func CreateRbacRolePrivilege(c *gin.Context) {
	ctx := c.Request.Context()
	req := forms.GrantRolePrivilege{}
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err, http.StatusBadRequest)
		return
	}

	rbacRolePrivilegeSrv, err := rbacsvc.GetRbacRolePrivilegeSvc()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	err = rbacRolePrivilegeSrv.CreateRbacRolePrivilege(ctx, req.RoleID, req.PrivilegeIDs)
	if err != nil {
		tilog.Error(ctx, "create rbacRolePrivilege fail:"+err.Error())
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	Success(c, nil, http.StatusOK)
}

// @Summary AddRbacRolePrivilege
// @tags ManagementPortalUser
// @Accept  json
// @Produce json
// @Param role body forms.GrantRolePrivilege true "AddRbacRolePrivilege"
// @Success 200 {object} forms.EmptyResponse
// @Router /rbac/role-privilege/add [post]
func AddRbacRolePrivilege(c *gin.Context) {
	ctx := c.Request.Context()
	req := forms.GrantRolePrivilege{}
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err, http.StatusBadRequest)
		return
	}

	rbacRolePrivilegeSrv, err := rbacsvc.GetRbacRolePrivilegeSvc()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	err = rbacRolePrivilegeSrv.AddRbacRolePrivilege(ctx, req.RoleID, req.PrivilegeIDs)
	if err != nil {
		tilog.Error(ctx, "add rbacRolePrivilege fail:"+err.Error())

		Fail(c, err, http.StatusInternalServerError)
		return
	}
	Success(c, nil, http.StatusOK)
}

// @Summary DeleteRbacRolePrivilege
// @tags ManagementPortalUser
// @Accept  json
// @Produce json
// @Param role body forms.RbacRolePrivilege true "DeleteRbacRolePrivilege"
// @Success 200 {object} forms.EmptyResponse
// @Router /rbac/role-privilege/delete [post]
func DeleteRbacRolePrivilege(c *gin.Context) {
	ctx := c.Request.Context()
	req := forms.RbacRolePrivilege{}
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err, http.StatusBadRequest)
		return
	}
	RbacRolePrivilegeSrv, err := rbacsvc.GetRbacRolePrivilegeSvc()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	err = RbacRolePrivilegeSrv.DeleteRbacRolePrivilege(ctx, req.RoleID, req.PrivilegeID)

	if err != nil {

		tilog.Error(ctx, "delete RbacRolePrivilege fail", zap.Error(err))
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	tilog.Info(ctx, "DeleteRbacRolePrivilege", zap.Any("RoleID", req.RoleID), zap.Any("PrivilegeID", req.PrivilegeID))
	Success(c, nil, http.StatusOK)
}

// @Summary ListRbacRoleRelatePrivileges
// @tags ManagementPortalUser
// @Accept  json
// @Produce json
// @Param role_id path uint64 true "role_id"
// @Success 200 {object} []forms.RbacRolePrivilege
// @Router /rbac/role-privilege/list/{role_id} [get]
func ListRbacRoleRelatePrivileges(c *gin.Context) {
	ctx := c.Request.Context()
	req := forms.GetRoleIDReq{}
	if err := c.ShouldBindUri(&req); err != nil {
		Fail(c, err, http.StatusBadRequest)
		return
	}
	rbacRolePrivilegeSrv, err := rbacsvc.GetRbacRolePrivilegeSvc()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	rolePrivileges, err := rbacRolePrivilegeSrv.ListRbacRolePrivilege(ctx, req.RoleID)

	if err != nil {

		Fail(c, err, http.StatusInternalServerError)
		return
	}
	var result []forms.RbacRolePrivilege
	for _, rp := range rolePrivileges {
		ret := forms.RbacRolePrivilege{
			ID:          rp.ID.Uint64(),
			RoleID:      rp.RbacRoleID.Uint64(),
			PrivilegeID: rp.RbacPrivilegeID.Uint64(),
		}
		result = append(result, ret)
	}

	Success(c, result, http.StatusOK)

}
