package central

import (
	"fmt"
	"strconv"

	"github.com/gin-gonic/gin"
	centralapi "github.com/tidbcloud/core-svc/idl/pbgen/proto/central"

	tidbmgmtservicev1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_mgmt_service/v1"
	"github.com/tidbcloud/tidb-management-service/tempo-wrapper/internal/api/types"
	apiutils "github.com/tidbcloud/tidb-management-service/tempo-wrapper/internal/api/utils"
	"github.com/tidbcloud/tidb-management-service/tempo-wrapper/pkg/grpc"
	mgmtgrpc "github.com/tidbcloud/tidb-management-service/tempo-wrapper/pkg/grpc/mgmt"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func CreateClusterWithConfig(ctx *gin.Context) {
	req := &tidbmgmtservicev1.CreateClusterWithClusterConfigurationRequest{}
	err := types.ShouldBindJSON(ctx, req)
	if err != nil {
		types.BadRequestResp(ctx, fmt.Errorf("bind request body failed: %w", err))
		return
	}

	// check org/project id
	orgId, err := strconv.ParseUint(ctx.Param("org_id"), 10, 64)
	if err != nil {
		types.BadRequestResp(ctx, fmt.Errorf("invalid org id: %w", err))
		return
	}
	projectId, err := strconv.ParseUint(ctx.Param("project_id"), 10, 64)
	if err != nil {
		types.BadRequestResp(ctx, fmt.Errorf("invalid project id: %w", err))
		return
	}

	// set org and project id
	req.Cluster.OrganizationId = orgId
	req.Cluster.ProjectId = projectId

	if req.GetCluster().GetDeployType() != tidbmgmtservicev1.DeployType_DEPLOY_TYPE_DEDICATED {
		types.BadRequestResp(ctx, fmt.Errorf("only support dedicated cluster"))
		return
	}

	// check new arch
	allow, err := apiutils.IsDedicatedAllow(ctx, orgId, projectId)
	if err != nil {
		types.InternalErrorResp(ctx, err)
		return
	}
	if !allow {
		types.BizErrorRequestResp(
			ctx,
			bizerr.New(bizerr.ErrCodeNotAllow3LayerArch, "not allow to create dedicated cluster in 3 layer arch"),
		)
		return
	}

	// create cluster
	cluster, err := mgmtgrpc.CreateClusterWithClusterConfiguration(grpc.NewContext(ctx), req)
	if err != nil {
		types.GrpcErrorResp(ctx, err)
		return
	}

	types.SuccessResp(ctx, &centralapi.CreateClusterResp{
		Id: cluster.ClusterId,
		BaseResp: &centralapi.BaseResp{
			ErrCode: int64(bizerr.ErrCodeOK),
			ErrMsg:  "",
		},
	})
}
