package run

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/workflow/plan"
)

func completionReplay(
	state *State,
	activation *Activation,
	completion Completion,
	output Values,
	rejectedCompletion *ResourceRejectedCompletionState,
) (Transition, bool, error) {
	if activation.ResourceRejectedCompletion != nil {
		if reflect.DeepEqual(activation.ResourceRejectedCompletion, rejectedCompletion) {
			return Transition{
				State: state, Intents: []Intent{},
				Events: []Event{{
					Kind: "completion_replayed", ActivationID: activation.ID, Port: completion.Port,
				}},
			}, true, nil
		}
		return Transition{}, true, fmt.Errorf("activation %q already rejected a different completion result", activation.ID)
	}
	if activation.Status != ActivationSucceeded {
		return Transition{}, false, nil
	}
	responderReplayMatches := true
	if activation.CallbackTaskWatch != nil {
		responderReplayMatches = strings.TrimSpace(completion.CallbackResponderAgentID) ==
			strings.TrimSpace(activation.CallbackTaskWatch.ResponderAgentID)
	}
	if len(activation.SelectedPorts) == 1 && activation.SelectedPorts[0] == completion.Port && reflect.DeepEqual(activation.Output, output) && reflect.DeepEqual(activation.Failure, completion.Failure) && responderReplayMatches {
		return Transition{State: state, Intents: []Intent{}, Events: []Event{{Kind: "completion_replayed", ActivationID: activation.ID, Port: completion.Port}}}, true, nil
	}
	return Transition{}, true, fmt.Errorf("activation %q already completed with a different result", activation.ID)
}

func (kernel *Kernel) freezeCompletionResponder(
	state *State,
	activation *Activation,
	opcode plan.ArtifactOpcode,
	rawResponderAgentID string,
) (string, string, bool, error) {
	responderAgentID := strings.TrimSpace(rawResponderAgentID)
	if opcode != plan.OpcodeSendMessageCallback {
		if responderAgentID != "" {
			return "", "", false, fmt.Errorf(
				"activation %q cannot freeze callback responder for opcode %q",
				activation.ID, opcode,
			)
		}
		return "", "", false, nil
	}
	if responderAgentID == "" {
		if err := restoreUnactivatedCallbackTaskWatch(state, activation); err != nil {
			return "", "", false, err
		}
		return "", "", false, nil
	}
	if _, err := freezeCallbackTaskWatchResponder(state, activation, responderAgentID); err != nil {
		return "", "", false, err
	}
	scopeID, activated, err := freezeFanOutActivatedResponder(state, activation, responderAgentID)
	if err != nil {
		return "", "", false, err
	}
	return responderAgentID, scopeID, activated, nil
}
