package action

import (
	"fmt"

	apprent "github.com/tidbcloud/devops/entity/approval"
	k8sent "github.com/tidbcloud/devops/entity/k8supgrade"
	"github.com/tidbcloud/devops/pkg/infra/errs"
)

type actorApproving struct {
	*baseActor
}

func (a *actorApproving) ContinueIfApproved() error {
	ctx := a.Context
	task := a.Task

	if task.ApprovalID == nil {
		return fmt.Errorf("phase is approving but approval id is nil")
	}

	appr, err := a.ApprovalService.GetApproval(ctx, *task.ApprovalID)
	if err != nil {
		return fmt.Errorf("get approval '%d' failed: %s", *task.ApprovalID, err)
	}

	switch appr.Status {
	case apprent.ApprovalStatusCancelled:
		err := a.PatchTask(ctx, PatchTaskToClose(k8sent.TaskStatusCancelled))
		if err != nil {
			return err
		}
	case apprent.ApprovalStatusRejected:
		err := a.PatchTask(ctx, PatchTaskToClose(k8sent.TaskStatusPending))
		if err != nil {
			return err
		}
	case apprent.ApprovalStatusApproved:
		err := a.PatchTask(ctx, func(current *k8sent.Task) error {
			current.Status = k8sent.TaskStatusRunning
			return nil
		})
		if err != nil {
			return err
		}
	default:
		return errs.RetriableErrorf("approval '%d' status is %s", *task.ApprovalID, appr.Status)
	}

	return nil
}

func (a *actorApproving) Cancel() error {
	ctx := a.Context
	task := a.Task

	if task.ApprovalID != nil {
		err := a.ApprovalService.CancelApproval(ctx, *task.ApprovalID)
		if err != nil {
			a.Logger.Info("failed to cancel approval operation", "error", err)
		}
	}

	return a.cancel()
}
