package regionserver

import (
	"context"
	"net/http"

	"github.com/go-resty/resty/v2"
	"github.com/samber/lo"
	regionaldedicatedv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/regional-server/v1"

	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

// Component Service
func (s *regionServerCliImpl) GetCompatNetwork(
	ctx context.Context,
	region *entity.Region,
	req *regionaldedicatedv1.GetCompatNetworkRequest,
) (*regionaldedicatedv1.CompatNetwork, bizerr.BizError) {
	resp, err := s.callRegion(
		ctx,
		region,
		http.MethodGet,
		operationMap["GetCompatNetwork"],
		func(request *resty.Request) *resty.Request {
			request.SetPathParam(vpcIdPathParameter, req.GetVpcId())
			return request
		},
	)
	if err != nil {
		return nil, err
	}

	var out regionaldedicatedv1.CompatNetwork
	if err := unmarshalOptions.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.WrapErrorWithCode(err, bizerr.ErrCodeRegionalAPI, "%s", err.Error())
	}
	return &out, nil
}

func (s *regionServerCliImpl) GetRegionConfig(
	ctx context.Context,
	region *entity.Region,
) (*regionaldedicatedv1.RegionConfig, bizerr.BizError) {
	resp, err := s.callRegion(
		ctx,
		region,
		http.MethodGet,
		operationMap["GetRegionConfig"],
		func(request *resty.Request) *resty.Request {
			return request
		},
	)
	if err != nil {
		return nil, err
	}

	var out regionaldedicatedv1.RegionConfig
	if err := unmarshalOptions.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.WrapErrorWithCode(err, bizerr.ErrCodeRegionalAPI, "%s", err.Error())
	}
	return &out, nil
}

func (s *regionServerCliImpl) ListAppBoxes(
	ctx context.Context,
	region *entity.Region,
	req *regionaldedicatedv1.ListAPPBoxesRequest,
) (*regionaldedicatedv1.ListAPPBoxesResponse, bizerr.BizError) {
	if req.GetTenantId() == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "tenant_id is required")
	}

	resp, err := s.callRegion(
		ctx,
		region,
		http.MethodGet,
		operationMap["ListAppBoxes"],
		func(request *resty.Request) *resty.Request {
			request.SetQueryParam(TenantIDParameter, req.GetTenantId())
			request.SetQueryParam(projectIDParameter, req.GetProjectId())
			request.SetQueryParam(clusterIdParameter, req.GetClusterId())
			request.SetQueryParamsFromValues(map[string][]string{
				statusesParameter: lo.Map(
					req.GetStatuses(),
					func(item regionaldedicatedv1.APPBox_Status, _ int) string { return item.String() },
				),
			})
			return request
		},
	)
	if err != nil {
		return nil, err
	}

	var out regionaldedicatedv1.ListAPPBoxesResponse
	if err := unmarshalOptions.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.WrapErrorWithCode(err, bizerr.ErrCodeRegionalAPI, "%s", err.Error())
	}

	return &out, nil
}
