package del

import (
	"context"

	biz_changefeed_model "github.com/tidbcloud/dataflow-service/app/models/biz_changefeed"
	"github.com/tidbcloud/dataflow-service/app/repo"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	"github.com/tidbcloud/dataflow-service/app/workflow"
	"github.com/tidbcloud/dataflow-service/app/workflow/action"
	"github.com/tidbcloud/dataflow-service/app/workflow/action/biz_changefeed"
	"github.com/tidbcloud/pkgv2/db"
	"go.uber.org/zap"
)

type ActionFinalStep struct {
	transProvider       db.TransProvider
	bizChangefeedRepo   repo.BizChangefeedRepo
	bizChangefeedHooker biz_changefeed_model.BizChangefeedHooker
}

func NewFinalAction(
	transProvider db.TransProvider,
	bizChangefeedRepo repo.BizChangefeedRepo,
	bizChangefeedHooker biz_changefeed_model.BizChangefeedHooker,
) *action.Wrapper {
	finalAction := &ActionFinalStep{
		transProvider:       transProvider,
		bizChangefeedRepo:   bizChangefeedRepo,
		bizChangefeedHooker: bizChangefeedHooker,
	}
	return action.MustNewActionWrapper(workflow.ActionBizChangefeedDeleteFinalStep, finalAction)
}

func (a *ActionFinalStep) Params() interface{} {
	return &biz_changefeed.CommonParams{}
}

func (a *ActionFinalStep) Run(ctx context.Context, logger *zap.Logger, params interface{}) error {
	commonParams := params.(*biz_changefeed.CommonParams)
	bizChangefeedEnt, bizErr := a.bizChangefeedRepo.Load(ctx, commonParams.BizChangefeedID)
	if bizErr != nil {
		return bizErr.Chain("load biz_changefeed entity")
	}

	return a.transProvider.Transaction(ctx, func(ctx context.Context) error {
		bizChangefeedEnt.OperationStatus = entity.BizChangefeedOperationStatusDeleted
		if bizErr := a.bizChangefeedRepo.Update(ctx, bizChangefeedEnt); bizErr != nil {
			return bizErr.Chain("update biz_changefeed status")
		}
		if bizErr := a.bizChangefeedRepo.Delete(ctx, bizChangefeedEnt.ID.Uint64()); bizErr != nil {
			return bizErr.Chain("delete biz_changefeed")
		}
		a.bizChangefeedHooker.HandleBizChangefeedEvent(ctx, entity.DeleteChangefeed, 0, bizChangefeedEnt)
		return nil
	})
}
