package metering

import (
	"context"
	"time"

	"github.com/tidbcloud/tiinf/monitor/tilog"

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

type RecordsCleaner struct {
	clusterMeteringRepo billingrepo.ClusterMeteringRepo
	billingReportRecord billingrepo.ReportRecordRepo
}

type RecordsCleanParam struct {
	RecordsToBeCleanedLimit          int
	ExpireDurationForClusterMetering time.Duration
	ExpireDurationForBillingRecord   time.Duration
}

func NewBillingRecordsCleaner(
	clusterMeteringRepo billingrepo.ClusterMeteringRepo,
	billingReportRecord billingrepo.ReportRecordRepo,
) *RecordsCleaner {
	return &RecordsCleaner{
		clusterMeteringRepo: clusterMeteringRepo,
		billingReportRecord: billingReportRecord,
	}
}

func (svc *RecordsCleaner) Clean(ctx context.Context, param *RecordsCleanParam) bizerr.BizError {
	logger := tilog.WithContextS(ctx)
	now := time.Now()

	recordsToBeDeletedBefore4ClusterMetering := now.Add(-param.ExpireDurationForClusterMetering)
	affectedLines, err := svc.clusterMeteringRepo.Clean(
		ctx,
		recordsToBeDeletedBefore4ClusterMetering,
		param.RecordsToBeCleanedLimit,
	)
	logger.Infof(
		"clean cluster metering, expiration=%s, affectedLines=%d, err=%s",
		param.ExpireDurationForClusterMetering,
		affectedLines,
		err,
	)

	recordsToBeDeletedBefore4BillingRecord := now.Add(-param.ExpireDurationForBillingRecord)
	affectedLines, err = svc.billingReportRecord.Clean(
		ctx,
		recordsToBeDeletedBefore4BillingRecord,
		param.RecordsToBeCleanedLimit,
	)
	logger.Infof(
		"clean billing record, expiration=%s, affectedLines=%d, err=%s",
		param.ExpireDurationForBillingRecord,
		affectedLines,
		err,
	)
	return nil
}
