package api

import (
	"net/http"

	rbac2 "github.com/tidbcloud/account/internel/svc/rbac"

	"github.com/spf13/viper"
	"github.com/tidbcloud/tiinf/monitor/tilog"

	"go.uber.org/zap"

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

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

	rbacPrivilegeSrv, err := rbac2.GetRbacPrivilegeSvc()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	privilege, err := rbacPrivilegeSrv.CreateRbacPrivilege(ctx, req.ResourceUri, req.Url, req.System, req.Description)
	if err != nil {

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

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

	rbacPrivilegeSrv, err := rbac2.GetRbacPrivilegeSvc()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}

	err = rbacPrivilegeSrv.UpdateRbacPrivilege(ctx, req.ID, req.ResourceUri, req.Url, req.System, req.Description)
	if err != nil {
		tilog.Error(ctx, "UpdateRbacPrivilege fail:", zap.Error(err))
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	tilog.Info(ctx, "UpdateRbacPrivilege", zap.Any("ID", req.ID), zap.Any(".ResourceUri", req.ResourceUri), zap.Any("Url", req.Url), zap.Any("System", req.System), zap.Any("Description", req.Description))

	Success(c, nil, http.StatusOK)
}

// @Summary ListRbacPrivileges
// @tags ManagementPortalUser
// @Accept  json
// @Produce json
// @Success 200 {object} forms.ListRbacPrivilegeResp
// @Router /rbac/privilege/list [get]
func ListRbacPrivileges(c *gin.Context) {
	ctx := c.Request.Context()
	req := rbac.ListPrivilegeParam{}
	if err := c.ShouldBindQuery(&req); err != nil {
		Fail(c, err, http.StatusBadRequest)
		return
	}
	rbacPrivilegeSrv, err := rbac2.GetRbacPrivilegeSvc()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	listResult, err := rbacPrivilegeSrv.ListRbacPrivileges(ctx, req)

	if err != nil {
		tilog.Error(ctx, "list ListRbacPrivileges fail:", zap.Error(err))

		Fail(c, err, http.StatusInternalServerError)
		return
	}

	Success(c, listResult, http.StatusOK)
}

// @Summary ListPrivilegeSystems
// @tags ManagementPortalUser
// @Accept  json
// @Produce json
// @Success 200 {object} forms.ListPrivilegeSystemsResp
// @Router /rbac/privilege/system-list [get]
func ListPrivilegeSystems(c *gin.Context) {
	ctx := c.Request.Context()
	tilog.Info(ctx, "get value from viper ", zap.Any("rbac.systems", viper.GetStringSlice("rbac.systems")))
	Systems := viper.GetStringSlice("rbac.systems")
	Success(c, Systems, http.StatusOK)
}

func GetRbacPrivilegeById(c *gin.Context) {
	ctx := c.Request.Context()
	req := GetIDReq(c)
	rbacPrivilegeSrv, err := rbac2.GetRbacPrivilegeSvc()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}

	rbacPrivilege, err := rbacPrivilegeSrv.GetRbacPrivilegeByID(ctx, req.ID)

	if err != nil {

		Fail(c, err, http.StatusInternalServerError)
		return
	}

	Success(c, rbacPrivilege, http.StatusOK)
}

// @Summary DeleteRbacPrivilege
// @tags ManagementPortalUser
// @Accept  json
// @Produce json
// @Param id path uint64 true "id"
// @Success 200 {object} forms.EmptyResponse
// @Router /rbac/privilege/delete/{id} [post]
func DeleteRbacPrivilege(c *gin.Context) {
	ctx := c.Request.Context()
	req := GetIDReq(c)
	rbacPrivilegeSrv, err := rbac2.GetRbacPrivilegeSvc()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	err = rbacPrivilegeSrv.DeleteRbacPrivilege(ctx, req.ID)
	if err != nil {
		tilog.Error(ctx, "DeleteRbacPrivilege fail:", zap.Error(err))

		Fail(c, err, http.StatusInternalServerError)
		return
	}
	rolePrivilegeSvc, _ := rbac2.GetRbacRolePrivilegeSvc()
	err = rolePrivilegeSvc.DeleteRbacRolePrivilegeByPrivilegeID(ctx, req.ID)
	tilog.Info(ctx, "DeleteRbacPrivilege", zap.Any("result", err == nil), zap.Any("privilege_id", req.ID))

	if err != nil {
		tilog.Warn(ctx, "DeleteRbacRolePrivilegeByPrivilegeID fail", zap.Any("privilege_id", req.ID), zap.Any("err", err))
	}
	Success(c, nil, http.StatusOK)
}
