package authactor

import (
	"fmt"
	"time"

	"github.com/tidbcloud/devops/entity/event"
	jmpent "github.com/tidbcloud/devops/entity/jump"
	"github.com/tidbcloud/devops/pkg/infra/errs"
	"github.com/tidbcloud/devops/pkg/infra/utils/pointer"
	timeutil "github.com/tidbcloud/devops/pkg/infra/utils/time"
	jmpsvcapi "github.com/tidbcloud/devops/pkg/service/jump/api"
)

type actorWhenCreated struct {
	*baseActor
}

func (a *actorWhenCreated) ExpireOrRefresh() error {
	currTime := time.Now()
	ctx := a.Context
	ins := a.JumpAuthorization

	if ins.ExpireAt == nil {
		return fmt.Errorf("phase is created but expired time is nil")
	}
	expireTime := *timeutil.TsToTime(ins.ExpireAt)

	if currTime.Before(expireTime) {
		err := a.refreshJumps(ctx)
		if err != nil {
			return fmt.Errorf("refresh jumps failed: %w", err)
		}

		return errs.RetriableErrorf("not expired")
	}

	// finalize jumps
	force := currTime.After(expireTime.Add(*a.Conf.ForceFinilizeJumpThreshold)) // If expired for a long time, force to finalize
	err := a.finalizeJumps(ctx, force, 60*time.Second)
	if err != nil {
		return fmt.Errorf("finalize jump failed: %w", err)
	}

	a.EventDetail = event.JumpEventExpire{
		Force: force,
	}

	err = a.PatchAuthorization(ctx, func(current *jmpent.Authorization) error {
		current.Phase = jmpent.AuthorizationPhaseExpired
		current.ClosedAt = pointer.Pointer(time.Now().Unix())
		return nil
	})
	if err != nil {
		return err
	}

	return nil
}

func (a *actorWhenCreated) Cancel(param jmpsvcapi.CancelAuthorizaitonParam) error {
	ctx := a.Context

	err := a.finalizeJumps(ctx, param.Force, time.Second*time.Duration(param.Timeout))
	if err != nil {
		return fmt.Errorf("finalize jump failed: %w", err)
	}

	a.EventDetail = event.JumpEventCancel{
		Force: param.Force,
	}

	// transition status to 'Cancel'
	return a.PatchAuthorization(ctx,
		func(current *jmpent.Authorization) error {
			current.Phase = jmpent.AuthorizationPhaseCanceled
			current.ClosedAt = pointer.Pointer(time.Now().Unix())
			return nil
		})
}
