using Workflow.Domain.Enums;
using Workflow.Domain.Exceptions;

using TaskStatus = Workflow.Domain.Enums.TaskStatus;

namespace Workflow.Domain.StateMachine;

public class TaskTransitionContext
{
    public bool AutoApproveOnTimeout { get; init; } = true;
}

public class TaskStateMachine
{
    public TaskStatus Transition(TaskStatus currentState, TaskOperation operation, TaskTransitionContext context)
    {
        return (currentState, operation) switch
        {
            (TaskStatus.Pending, TaskOperation.Approve) => TaskStatus.Approved,
            (TaskStatus.Pending, TaskOperation.Reject) => TaskStatus.Rejected,
            (TaskStatus.Pending, TaskOperation.Transfer) => TaskStatus.Transferred,
            (TaskStatus.Pending, TaskOperation.Delegate) => TaskStatus.Delegated,
            (TaskStatus.Pending, TaskOperation.TimeoutAutoProcess) =>
                context.AutoApproveOnTimeout ? TaskStatus.Approved : TaskStatus.Rejected,
            (TaskStatus.Delegated, TaskOperation.DelegateComplete) => TaskStatus.Pending,
            _ => throw new InvalidStateTransitionException(
                $"Invalid task state transition: cannot perform '{operation}' on task in '{currentState}' state.")
        };
    }
}
