package common

import (
	"context"

	backupModel "github.com/tidbcloud/dataflow-service/app/models/backup"
	"github.com/tidbcloud/dataflow-service/app/models/domain"
	crrfRepo "github.com/tidbcloud/dataflow-service/app/repo/crrf"
	"github.com/tidbcloud/dataflow-service/app/workflow"
	"github.com/tidbcloud/dataflow-service/app/workflow/action"
	bizerr_wrapper "github.com/tidbcloud/dataflow-service/pkg/bizerr-wrapper"
	"go.uber.org/zap"
)

type modifyReplicationRTCCRRFParams struct {
	ClusterID uint64 `json:"cluster_id"`
	Enable    bool   `json:"enable"`
}

type modifyReplicationRTCCRRFAction struct {
	backupSettingModel backupModel.BackupSettingModel
	crrfSettingRepo    crrfRepo.CRRFSettingRepo
}

// NewCRRFModifyReplicationRTCAction returns a Wrapper that enables or disables S3 RTC
// for a cluster synchronously via BackupSettingModel.ModifyReplicationRTC.
// It reads masterBucketID from CRRFSetting to bypass the temporarily-zero BucketId
// in BackupSetting.Bucket during dual-region disable transitions.
func NewCRRFModifyReplicationRTCAction(
	backupSettingModel backupModel.BackupSettingModel,
	crrfSettingRepo crrfRepo.CRRFSettingRepo,
) *action.Wrapper {
	return action.MustNewActionWrapper(
		workflow.ActionCRRFModifyReplicationRTC,
		&modifyReplicationRTCCRRFAction{
			backupSettingModel: backupSettingModel,
			crrfSettingRepo:    crrfSettingRepo,
		},
	)
}

func (a *modifyReplicationRTCCRRFAction) Params() interface{} {
	return &modifyReplicationRTCCRRFParams{}
}

func (a *modifyReplicationRTCCRRFAction) Run(ctx context.Context, logger *zap.Logger, params interface{}) error {
	p := params.(*modifyReplicationRTCCRRFParams)

	crrfSetting, err := a.crrfSettingRepo.GetByClusterID(ctx, p.ClusterID)
	if err != nil {
		logger.Warn("load crrf setting failed", zap.Uint64("clusterID", p.ClusterID), zap.Error(err))
		return err
	}
	if crrfSetting.MasterBucketID == 0 {
		logger.Error("master bucket ID is not set in crrf setting, cannot modify replication RTC",
			zap.Uint64("clusterID", p.ClusterID))
		return bizerr_wrapper.NewInternalErr("master bucket ID is not set for cluster %d", p.ClusterID)
	}

	logger.Info("modifying replication RTC",
		zap.Uint64("clusterID", p.ClusterID),
		zap.Bool("enable", p.Enable),
		zap.Uint64("masterBucketID", uint64(crrfSetting.MasterBucketID)))
	return a.backupSettingModel.ModifyReplicationRTC(ctx, &domain.ReplicationRTCModificationReq{
		ClusterID: p.ClusterID,
		Enable:    p.Enable,
		BucketID:  uint64(crrfSetting.MasterBucketID),
	})
}
