package region

import (
	"context"
	"time"

	"github.com/pingcap/log"
	dataplanemanagerv1 "github.com/tidbcloud/cluster-service-ng/api/tidbcloud/dataplane-manager/v1"
	"go.uber.org/zap"
	"k8s.io/utils/ptr"

	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 (s *service) UpdateRegionOpsAuditLogSetting(
	ctx context.Context,
	request *globalngv1.UpdateRegionOpsAuditLogSettingRequest,
) (*globalngv1.UpdateRegionOpsAuditLogSettingResponse, bizerr.BizError) {
	if request == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "request is nil")
	}

	cloudRegion, err := s.getRegionByIdentifier(ctx, request.GetRegion())
	if err != nil {
		return nil, err
	}

	if cloudRegion.GetServicePlan() != globalcommonv1.ServicePlan_BYOC {
		return nil, bizerr.New(bizerr.ErrCodeParams, "ops audit log setting can only be updated for BYOC regions")
	}

	tErr := s.transaction.Transaction(ctx, func(ctx context.Context) error {
		err = s.regionRepo.UpsertRegionOpsAuditLogSetting(ctx, &entity.RegionOpsAuditLogSetting{
			RegionID:                 cloudRegion.RegionID,
			RegionOpsAuditLogSetting: request.OpsAuditLogSetting,
		})
		if err != nil {
			return err
		}

		cloudRegion, err = s.regionRepo.GetByLogicalName(ctx, cloudRegion.GetLogicalName())
		if err != nil {
			return err
		}

		err = s.nextgenCli.SetKongAuditLogSetting(ctx, cloudRegion, &dataplanemanagerv1.SetKongAuditLogSettingRequest{
			Enabled:     cloudRegion.OpsAuditLogSetting.GetEnabled(),
			MaxSize:     int32(cloudRegion.OpsAuditLogSetting.GetLogRotation().GetFileSizeLimitInMb()),
			MaxLifetime: ptr.To(int32(cloudRegion.OpsAuditLogSetting.GetLogRotation().GetRotationIntervalInMin()) * int32(time.Minute/time.Second)),
			BucketUrl:   cloudRegion.GetOpsAuditLogSetting().GetLogLocation().GetBucketUri(),
			Region:      cloudRegion.Id.String(),
			ProviderIdentity: &dataplanemanagerv1.SetKongAuditLogSettingRequest_ProviderIdentity{
				CloudRoleIdentity: cloudRegion.GetOpsAuditLogSetting().GetLogLocation().GetRoleArn(),
				ExternalId:        cloudRegion.GetOpsAuditLogSetting().GetLogLocation().GetExternalId(),
			},
		})
		if err != nil {
			log.Error("set kong audit log setting", zap.Error(err))
			return err
		}

		return nil
	})
	if tErr != nil {
		return nil, bizerr.WrapErrorWithCode(tErr, bizerr.GeneralInternalErrorCode, "update region ops audit log setting failed")
	}

	// get region again to return
	cloudRegion, err = s.getRegionByIdentifier(ctx, request.GetRegion())
	if err != nil {
		return nil, err
	}

	response := &globalngv1.UpdateRegionOpsAuditLogSettingResponse{
		Region: cloudRegion.Region,
	}
	return response, nil
}
