package rcuquota

import (
	"context"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func CalculateMinRcuByQuota(maxRcu int64, rcuQuota *entity.RcuQuota) int64 {
	baseline := int64(rcuQuota.GetMinimalRcuBaseline())
	if baseline == 0 {
		baseline = 5000
	}
	coefficient := float64(rcuQuota.GetMinimalRcuCoefficient())
	if coefficient == 0 {
		coefficient = 0.25
	}

	dynamicMin := max(int64(float64(maxRcu)*coefficient), baseline)
	return dynamicMin
}

func (s *serviceImpl) CalculateMinRcu(
	ctx context.Context,
	request *globalngv1.CalculateMinRcuRequest,
) (*globalngv1.CalculateMinRcuResponse, bizerr.BizError) {
	ctx, span := tracer.Start(ctx, "Domain.CalculateMinRcu")
	defer span.End()

	if request == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "request cannot be nil")
	}

	if request.GetOrganizationId() == 0 {
		return nil, bizerr.New(bizerr.ErrCodeParams, "organizationId cannot be empty")
	}

	if request.GetServicePlan() == globalcommonv1.ServicePlan_SERVICE_PLAN_UNSPECIFIED {
		return nil, bizerr.New(bizerr.ErrCodeParams, "service plan cannot be empty")
	}

	if request.GetMaxRcu() <= 0 {
		return nil, bizerr.New(bizerr.ErrCodeParams, "max rcu must be greater than 0")
	}

	if request.GetRegionId() == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "region id cannot be empty")
	}

	rcuQuota, err := s.rcuQuotaRepo.Load(ctx, request.GetOrganizationId(), request.GetServicePlan().String())
	if err != nil {
		return nil, err
	}

	return &globalngv1.CalculateMinRcuResponse{
		MinRcu: CalculateMinRcuByQuota(request.GetMaxRcu(), rcuQuota),
	}, nil
}
