package api

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/dbaas/admin/forms"
)

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

	internalRole := buildInternalRole(req)
	internalRole.Id = 0

	userContext := GetUserContext(c)

	item, err := userContext.UpsertRole(internalRole)
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}

	Success(c, buildAPIRoleItem(item), http.StatusOK)
}

// @Summary ListCentralRoles
// @tags ManagementPortalUser
// @Accept  json
// @Produce json
// @Success 200 {object} forms.ListRolesResp
// @Router /roles [get]
func ListCentralRoles(c *gin.Context) {
	userContext := GetUserContext(c)

	dbRecords, err := userContext.ListRoles()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}
	total, err := userContext.GetRolesCount()
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}

	items := []forms.Role{}
	for _, item := range dbRecords {
		items = append(items, buildAPIRoleItem(item))
	}

	result := forms.ListRolesResp{
		Total: total,
		Items: items,
	}

	Success(c, result, http.StatusOK)
}

// @Summary DeleteCentralRole
// @Tags ManagementPortalUser
// @Description DeleteCentralRole
// @Accept  json
// @Produce json
// @Param role_id path string true "role_id"
// @Success 200 {object} forms.EmptyResponse
// @Router /roles/{role_id} [delete]
func DeleteCentralRole(c *gin.Context) {
	req := forms.GetRoleIDReq{}
	if err := c.ShouldBindUri(&req); err != nil {
		Fail(c, err, http.StatusBadRequest)
		return
	}

	userContext := GetUserContext(c)
	if err := userContext.DeleteRole(req.RoleID); err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}

	Success(c, nil, http.StatusOK)
}

// @Summary GetCentralRole
// @Tags ManagementPortalUser
// @Description GetCentralRole
// @Accept  json
// @Produce json
// @Param role_id path string true "role_id"
// @Success 200 {object} forms.Role
// @Router /roles/{role_id} [get]
func GetCentralRole(c *gin.Context) {
	req := forms.GetRoleIDReq{}
	if err := c.ShouldBindUri(&req); err != nil {
		Fail(c, err, http.StatusBadRequest)
		return
	}

	userContext := GetUserContext(c)
	item, err := userContext.GetRoleByID(req.RoleID)
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}

	Success(c, buildAPIRoleItem(item), http.StatusOK)
}

// @Summary UpdateCentralRole
// @Tags ManagementPortalUser
// @Description UpdateCentralRole
// @Accept  json
// @Produce json
// @Param role_id path string true "role_id"
// @Param role body forms.Role true "UpdateCentralRole"
// @Success 200 {object} forms.Role
// @Router /roles/{role_id} [put]
func UpdateCentralRole(c *gin.Context) {
	reqUri := forms.GetRoleIDReq{}
	if err := c.ShouldBindUri(&reqUri); err != nil {
		Fail(c, err, http.StatusBadRequest)
		return
	}
	req := forms.Role{}
	if err := c.ShouldBindJSON(&req); err != nil {
		Fail(c, err, http.StatusBadRequest)
		return
	}
	req.ID = reqUri.RoleID

	userContext := GetUserContext(c)
	role := buildInternalRole(req)

	internalRole, err := userContext.UpsertRole(role)
	if err != nil {
		Fail(c, err, http.StatusInternalServerError)
		return
	}

	Success(c, buildAPIRoleItem(internalRole), http.StatusOK)
}
