package br

import (
	"context"
	"time"

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

type QueryBackupSettingFilter struct {
	RegionIds                []string
	ServicePlans             []string
	ClusterIds               []uint64
	Name                     string
	SharedPoolIds            []uint64
	TenantIds                []uint64
	Modes                    []schema.BackupMode
	States                   []schema.BackupSettingState
	ExcludeStates            []schema.BackupSettingState
	LastScheduleUpdatedAtGte *time.Time
	DeletedAtGte             *time.Time
	DeletedAtLte             *time.Time
	Deleted                  *bool
	OrderBy                  *string
}

type BackupReconciliationExclusion struct {
	StartAt time.Time
	EndAt   *time.Time
}

//go:generate go run go.uber.org/mock/mockgen@latest -source=$GOFILE -package=mock_$GOPACKAGE -destination=./mock_$GOPACKAGE/mock_$GOFILE
type BackupSettingRepo interface {
	Create(ctx context.Context, backupSetting *entity.BackupSetting) bizerr.BizError
	Save(ctx context.Context, backupSetting *entity.BackupSetting) bizerr.BizError
	BatchUpdateName(ctx context.Context, tenantId uint64, clusterNames map[uint64]string) bizerr.BizError
	UpdateLastAutoBackupAt(ctx context.Context, clusterId uint64, lastAutoBackupAt *time.Time) (time.Time, bizerr.BizError)
	OpenBackupReconciliationExclusion(ctx context.Context, sharedPoolId uint64, operationId string, startAt time.Time) bizerr.BizError
	CloseBackupReconciliationExclusion(ctx context.Context, sharedPoolId uint64, endAt time.Time) bizerr.BizError
	ListBackupReconciliationExclusions(
		ctx context.Context,
		sharedPoolId uint64,
		startAt, endAt time.Time,
	) ([]BackupReconciliationExclusion, bizerr.BizError)
	Delete(ctx context.Context, clusterId uint64) bizerr.BizError
	// Get will return the deleted backup setting if the cluster is deleted
	Get(ctx context.Context, clusterId uint64) (*entity.BackupSetting, bizerr.BizError)
	// GetActiveForUpdate locks and returns a non-deleted backup setting. It must
	// be called inside the transaction that performs the guarded mutation.
	GetActiveForUpdate(ctx context.Context, clusterId uint64) (*entity.BackupSetting, bizerr.BizError)
	// Notice: this method will return the deleted backup settings, unless you explicitly set the Deleted to false
	// If there two many backup settings, you should use pagination to query the backup settings
	UnscopedQuery(
		ctx context.Context,
		filter *QueryBackupSettingFilter,
		page *pagination.Page,
	) ([]*entity.BackupSetting, bizerr.BizError)
	// UnscopedCount will return the total number of the backup settings
	UnscopedCount(ctx context.Context, filter *QueryBackupSettingFilter) (int64, bizerr.BizError)
	// if the backup setting is deleted, we need to transit the state of the backup setting to expired or cleanup if needed
	TransitStateAfterBackupDeletedIfNeeded(ctx context.Context, clusterId uint64) bizerr.BizError
}
