package action

import (
	clusterngv1beta "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"
	"github.com/tidbcloud/fastflow/pkg/entity/run"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/adapter/regionalserver"
	exportrepo "github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/export"
	regionrepo "github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/region"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/service/workflow/common"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/workflow"
)

const (
	CleanExportAction = "clean_export"
)

type CleanExportActionStruct struct {
	exportRepo        exportrepo.ExportRepo
	regionRepo        regionrepo.Repo
	regionalserverCli regionalserver.Client
}

func NewCleanExportAction(
	exportRepo exportrepo.ExportRepo,
	regionRepo regionrepo.Repo,
	regionalserverCli regionalserver.Client,
) *CleanExportActionStruct {
	return &CleanExportActionStruct{
		exportRepo:        exportRepo,
		regionRepo:        regionRepo,
		regionalserverCli: regionalserverCli,
	}
}

func (a *CleanExportActionStruct) Name() string {
	return CleanExportAction
}

func (a *CleanExportActionStruct) ParameterNew() any {
	return &common.ExportParameter{}
}

func (a *CleanExportActionStruct) Run(ctx run.ExecuteContext, params any) error {
	cctx, span := workflow.GenerateContext(ctx)
	defer span.End()

	clusterId, exportId, err1 := common.GetExportParams(params)
	if err1 != nil {
		tilog.Error(cctx, "clean export action: invalid params", zap.Error(err1))
		return err1
	}

	tilog.Info(cctx, "clean export action start", zap.String("cluster_id", clusterId), zap.String("export_id", exportId))

	ent, err := a.exportRepo.GetByClusterAndExportId(cctx, clusterId, exportId)
	if err != nil {
		tilog.Error(cctx, "clean export action: failed to get export", zap.Error(err), zap.String("export_id", exportId))
		return err
	}

	region, err := a.regionRepo.Get(cctx, ent.RegionId)
	if err != nil {
		tilog.Error(cctx, "clean export action: failed to get region", zap.Error(err), zap.Uint64("region_id", ent.RegionId))
		return err
	}

	err = a.regionalserverCli.CleanExport(cctx, region, &clusterngv1beta.CancelExportRequest{
		ClusterId: clusterId,
		ExportId:  exportId,
	})
	if err != nil {
		if err.ErrCode() == bizerr.ErrCodeRecordNotFound {
			tilog.Info(cctx, "clean export action skip: export not found", zap.String("export_id", exportId))
			return nil
		}
		tilog.Error(cctx, "regional clean export failed", zap.Error(err), zap.String("export_id", exportId))
		return err
	}

	tilog.Info(cctx, "clean export action done", zap.String("export_id", exportId))
	return nil
}
