package workflow

import (
	"context"
	"time"

	"github.com/tidbcloud/chaos-svc/idl/pbgen/proto/chaos"
	"github.com/tidbcloud/chaos-svc/pkg/domain/entity"
	"github.com/tidbcloud/chaos-svc/pkg/domain/facade"
	"github.com/tidbcloud/chaos-svc/pkg/domain/repo"
	"github.com/tidbcloud/pkgv2/bizerr"
)

type CreateWorkflowSvc interface {
	Execute(ctx context.Context, params *CreateWorkflowParam) (*entity.Workflow, bizerr.BizError)
}

type CreateWorkflowParam struct {
	TiDBCluster facade.TiDBCluster
	UserID      uint64
	Draft       bool
	Summary     string
	Spec        entity.WorkflowSpec
}

type createWorkflowImp struct {
	workflowRepo repo.WorkflowRepo
	infraFacade  facade.Infra
}

func NewCreateWorkflowSvc(
	workflowRepo repo.WorkflowRepo,
	infraFacade facade.Infra,
) CreateWorkflowSvc {
	return &createWorkflowImp{
		workflowRepo: workflowRepo,
		infraFacade:  infraFacade,
	}
}

func (imp *createWorkflowImp) Execute(ctx context.Context, params *CreateWorkflowParam) (*entity.Workflow, bizerr.BizError) {
	workflowEntity, err := buildWorkflowEntity(params)
	if err != nil {
		return nil, err
	}
	if err := imp.workflowRepo.Save(ctx, workflowEntity); err != nil {
		return nil, err
	}
	if workflowEntity.Status != chaos.ExperimentStatus_EXPERIMENT_STATUS_DRAFT {
		if err := imp.infraFacade.CreateWorkflowIgnoreExist(ctx, workflowEntity); err != nil {
			return nil, err
		}
	}
	return workflowEntity, nil
}

func buildWorkflowEntity(params *CreateWorkflowParam) (*entity.Workflow, bizerr.BizError) {
	status := chaos.ExperimentStatus_EXPERIMENT_STATUS_DRAFT
	if !params.Draft {
		status = chaos.ExperimentStatus_EXPERIMENT_STATUS_RUNNING
	}
	return &entity.Workflow{
		ClusterID:   params.TiDBCluster.ClusterID,
		ProjectID:   params.TiDBCluster.ProjectID,
		Status:      status,
		Message:     "",
		Spec:        params.Spec,
		CreatedByID: params.UserID,
		CreatedAt:   time.Time{},
		Summary:     params.Summary,
		Versioning:  0,
	}, nil
}
