package br

import (
	"context"
	"strconv"
	"strings"

	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"google.golang.org/protobuf/proto"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/infra/repoimpl/schema"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func (s *serviceImpl) OverrideFlexibleBackupRetention(
	ctx context.Context,
	req *globalngv1.OverrideFlexibleBackupRetentionRequest,
) (*globalngv1.BackupSetting, bizerr.BizError) {
	if req == nil || strings.TrimSpace(req.GetReason()) == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "reason is required")
	}
	if req.GetRetentionDays() < MinOverrideFlexibleRetentionDays || req.GetRetentionDays() > MaxFlexibleRetentionDays {
		return nil, bizerr.New(
			bizerr.ErrCodeParams,
			"retention_days must be between %d and %d",
			MinOverrideFlexibleRetentionDays,
			MaxFlexibleRetentionDays,
		)
	}
	clusterID, err := strconv.ParseUint(req.GetClusterId(), 10, 64)
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster_id is invalid")
	}
	setting, berr := s.backupSettingRepo.Get(ctx, clusterID)
	if berr != nil {
		return nil, berr
	}
	if setting.Mode != schema.BackupModeFlexibleRetention {
		return nil, bizerr.New(bizerr.ErrCodeParams, "retention override is only supported for flexible retention")
	}
	tilog.Info(ctx, "override flexible backup retention",
		zap.String("cluster_id", req.GetClusterId()),
		zap.Int32("retention_days", req.GetRetentionDays()),
		zap.String("reason", req.GetReason()))
	return s.updateBackupSetting(ctx, &globalngv1.UpdateBackupSettingRequest{
		BackupSetting: &globalngv1.BackupSetting{
			ClusterId:          req.GetClusterId(),
			Mode:               globalngv1.BackupSetting_FLEXIBLE_RETENTION,
			RetentionDays:      proto.Int32(req.GetRetentionDays()),
			DailyBackupTimeUtc: proto.String(setting.DailyBackupTimeUTC),
		},
	}, backupSettingUpdateSourceIncidentOverride)
}
