package appbox

import (
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	regionalapiv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/regional-server/v1"
	bizerr "github.com/tidbcloud/infra-provider/regional-server/pkg/common/errors"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/common/message"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/router/interceptor"
	sevapppbox "github.com/tidbcloud/infra-provider/regional-server/pkg/service/appbox"
)

type APPBoxHandler struct {
	appboxsvc *sevapppbox.APPBoxService
}

func NewAPPBoxHandler(svc *sevapppbox.APPBoxService) *APPBoxHandler {
	return &APPBoxHandler{
		appboxsvc: svc,
	}
}

func (r *APPBoxHandler) ListAPPBoxes(c *gin.Context) {
	tenantId := c.Query("tenantId")
	projectId := c.Query("projectId")
	clusterId := c.Query("clusterId")
	statuses := c.QueryArray("statuses")
	filters := make([]regionalapiv1.APPBox_Status, 0, len(statuses))
	for _, v := range statuses {
		filters = append(filters,
			regionalapiv1.APPBox_Status(regionalapiv1.APPBox_Status_value[strings.ToUpper(v)]))
	}
	req := &regionalapiv1.ListAPPBoxesRequest{
		TenantId:  tenantId,
		ProjectId: projectId,
		ClusterId: clusterId,
		Statuses:  filters,
	}
	if err := (&message.ListAPPBoxesReqValidatable{ListAPPBoxesRequest: req}).Validate(); err != nil {
		interceptor.Fail(c, bizerr.New(bizerr.ParameterInvalid, err.Error()))
		return
	}
	resp, err := r.appboxsvc.ListAPPBoxes(c, req)
	if err != nil {
		interceptor.Fail(c, err)
		return
	}
	interceptor.SucceedPb(c, http.StatusOK, resp)
}

func (r *APPBoxHandler) CreateAPPBox(c *gin.Context) {
	req := &message.CreateAPPBoxReq{}
	if ok := interceptor.HandleJsonRequestFromBody(c, req); !ok {
		return
	}
	if err := req.Validate(); err != nil {
		interceptor.Fail(c, bizerr.New(bizerr.ParameterInvalid, err.Error()))
		return
	}
	resp, err := r.appboxsvc.CreateAPPBox(c, req)
	if err != nil {
		interceptor.Fail(c, err)
		return
	}
	interceptor.Succeed(c, http.StatusAccepted, resp)
}

func (r *APPBoxHandler) DeleteAPPBox(c *gin.Context) {
	req := &regionalapiv1.DeleteAPPBoxRequest{
		Name: c.Param("name"),
	}
	if err := (&message.DeleteAPPBoxReqValidatable{DeleteAPPBoxRequest: req}).Validate(); err != nil {
		interceptor.Fail(c, bizerr.New(bizerr.ParameterInvalid, err.Error()))
		return
	}
	if err := r.appboxsvc.DeleteAPPBox(c, req); err != nil {
		interceptor.Fail(c, err)
		return
	}
	interceptor.SucceedPb(c, http.StatusAccepted, nil)
}

func (r *APPBoxHandler) GetAPPBox(c *gin.Context) {
	req := &regionalapiv1.GetAPPBoxRequest{
		Name: c.Param("name"),
	}
	if err := (&message.GetAPPBoxReqValidatable{GetAPPBoxRequest: req}).Validate(); err != nil {
		interceptor.Fail(c, bizerr.New(bizerr.ParameterInvalid, err.Error()))
		return
	}
	resp, err := r.appboxsvc.GetAPPBox(c, req)
	if err != nil {
		interceptor.Fail(c, err)
		return
	}
	interceptor.SucceedPb(c, http.StatusOK, resp)
}
