package regionalserver

import (
	"context"
	"net/http"

	"github.com/go-resty/resty/v2"
	clusterngv1beta "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"

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

func (s *regionalServerCliImpl) CreatePrivateLinkService(
	ctx context.Context,
	region *entity.Region,
	req *clusterngv1beta.CreatePrivateLinkServiceRequest,
) (*clusterngv1beta.PrivateLinkService, bizerr.BizError) {
	body, err := marshalOptions.Marshal(req.GetPrivateLinkService())
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeJsonMarshal, "%s", err.Error())
	}
	resp, berr := s.callRegion(
		ctx,
		region,
		http.MethodPost,
		operationMap["CreatePrivateLinkService"],
		func(request *resty.Request) *resty.Request {
			request.SetPathParam(clusterIdParameter, req.GetClusterId())
			request.SetPathParam(tidbGroupIdPathParameter, req.GetPrivateLinkService().GetTidbGroupId())
			request.SetBody(body)
			return request
		},
	)
	if berr != nil {
		return nil, berr
	}

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

	return &out, nil
}

func (s *regionalServerCliImpl) UpdatePrivateLinkService(
	ctx context.Context,
	region *entity.Region,
	req *clusterngv1beta.UpdatePrivateLinkServiceRequest,
) (*clusterngv1beta.PrivateLinkService, bizerr.BizError) {
	body, err := marshalOptions.Marshal(req)
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeJsonMarshal, "%s", err.Error())
	}
	resp, berr := s.callRegion(
		ctx,
		region,
		http.MethodPut,
		operationMap["UpdatePrivateLinkService"],
		func(request *resty.Request) *resty.Request {
			request.SetPathParam(clusterIdParameter, req.GetClusterId())
			request.SetPathParam(tidbGroupIdPathParameter, req.GetTidbGroupId())
			request.SetPathParam(privateLinkServiceIdPathParameter, req.GetPrivateLinkServiceId())
			request.SetBody(body)
			return request
		},
	)
	if berr != nil {
		return nil, berr
	}

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

	return &out, nil
}

func (s *regionalServerCliImpl) GetPrivateLinkService(
	ctx context.Context,
	region *entity.Region,
	req *clusterngv1beta.GetPrivateLinkServiceRequest,
) (*clusterngv1beta.PrivateLinkService, bizerr.BizError) {
	resp, berr := s.callRegion(
		ctx,
		region,
		http.MethodGet,
		operationMap["GetPrivateLinkService"],
		func(request *resty.Request) *resty.Request {
			request.SetPathParam(clusterIdParameter, req.GetClusterId())
			request.SetPathParam(tidbGroupIdPathParameter, req.GetTidbGroupId())
			request.SetPathParam(privateLinkServiceIdPathParameter, req.GetPrivateLinkServiceId())
			return request
		},
	)
	if berr != nil {
		return nil, berr
	}

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

	return &out, nil
}

func (s *regionalServerCliImpl) DeletePrivateLinkService(
	ctx context.Context,
	region *entity.Region,
	req *clusterngv1beta.DeletePrivateLinkServiceRequest,
) bizerr.BizError {
	deleteResp, berr := s.callRegion(
		ctx,
		region,
		http.MethodDelete,
		operationMap["DeletePrivateLinkService"],
		func(request *resty.Request) *resty.Request {
			request.SetPathParam(clusterIdParameter, req.GetClusterId())
			request.SetPathParam(tidbGroupIdPathParameter, req.GetTidbGroupId())
			request.SetPathParam(privateLinkServiceIdPathParameter, req.GetPrivateLinkServiceId())
			return request
		},
	)
	if berr != nil {
		if deleteResp != nil && deleteResp.StatusCode() == http.StatusNotFound {
			return bizerr.New(bizerr.ErrCodeRecordNotFound, "private link service not found")
		}
		return berr
	}
	return nil
}
