package promptcompiler

import (
	"fmt"
	"strings"

	"github.com/tidbcloud/AgentTeam/desktop/internal/types"
)

func formatActiveTaskTargetPrompt(target types.ActiveTaskTarget, sendMessageTool string) string {
	target = target.Normalize()
	if !target.Valid() {
		return ""
	}
	sendMessageTool = strings.TrimSpace(sendMessageTool)
	if sendMessageTool == "" {
		sendMessageTool = "message_send"
	}
	taskScopeSendCall := ""
	if taskScope := strings.TrimSpace(target.TaskScope); taskScope != "" {
		taskScopeSendCall = formatMessageSendCall(sendMessageTool, taskScope)
	}
	return renderRegisteredPromptText("event.active_task_routing", newActiveTaskPromptInput(ActiveTaskTemplateData{
		TaskNumber: target.TaskNumber, Channel: strings.TrimSpace(target.Channel), TaskScope: strings.TrimSpace(target.TaskScope), Source: strings.TrimSpace(target.Source),
		ThreadTarget: strings.TrimSpace(target.ThreadTarget), Role: strings.TrimSpace(target.Role), ParentTaskNumber: target.ParentTaskNumber, RootTaskNumber: target.RootTaskNumber,
		TaskScopeSendCall: taskScopeSendCall, CheckpointCommand: fmt.Sprintf("agentteam exec task checkpoint '{\"channel\":%q,\"number\":%d,\"summary\":\"...\"}'", target.Channel, target.TaskNumber),
	}))
}

// FormatActiveTaskDirectMessageRoutingPrompt describes how a normal
// channel/DM/thread wake should behave while an active task target exists. Task
// scope messages carry their own message_send target, so this only applies to
// plain human-visible messages.
func FormatActiveTaskDirectMessageRoutingPrompt(target, messageType, sendMessageTool, readHistoryTool string) string {
	target = strings.TrimSpace(target)
	if target == "" || strings.TrimSpace(messageType) != "" {
		return ""
	}
	sendMessageTool = strings.TrimSpace(sendMessageTool)
	if sendMessageTool == "" {
		sendMessageTool = "message_send"
	}
	readHistoryTool = strings.TrimSpace(readHistoryTool)
	if readHistoryTool == "" {
		readHistoryTool = "message_history_read"
	}

	return renderRegisteredPromptText("event.active_task_normal_routing", newActiveTaskNormalPromptInput(ActiveTaskNormalRoutingTemplateData{
		Target: target, ReadHistoryTool: readHistoryTool, SendMessageTool: sendMessageTool, SendCall: formatMessageSendCall(sendMessageTool, target),
	}))
}

// SelectPromptActiveTaskTarget returns the task-routing target that should be
// rendered for this concrete wake. Session-sticky targets from prior task tool
// calls remain useful runtime state, but ordinary channel/DM/thread messages
// should not inherit them unless the current message is explicitly task-routed.
func SelectPromptActiveTaskTarget(bindingTarget types.ActiveTaskTarget, msg types.InboxMessage) types.ActiveTaskTarget {
	if target := msg.ResolvedActiveTaskTarget(); activeTaskTargetAppliesToPrompt(target) {
		return target.Normalize()
	}
	if target := bindingTarget.Normalize(); activeTaskTargetAppliesToPrompt(target) {
		return target
	}
	return types.ActiveTaskTarget{}
}

func activeTaskTargetAppliesToPrompt(target types.ActiveTaskTarget) bool {
	target = target.Normalize()
	if !target.Valid() {
		return false
	}
	switch strings.TrimSpace(target.Source) {
	case "task_dispatch", "thread_focus", "thread_current_focus", "human_selected":
		return true
	default:
		return false
	}
}

// FormatAgentAuthoredWakeGuidance keeps agent @mentions as real wakes while
// preventing social acknowledgement loops between runtimes.
func FormatAgentAuthoredWakeGuidance(msg types.InboxMessage) string {
	if msg.AuthorIdentity().ActorType != "agent" {
		return ""
	}
	if strings.TrimSpace(msg.MessageType) == "reaction" {
		return ""
	}
	return renderRegisteredPromptText("event.agent_authored_wake_guidance", newEmptyPromptInput(PromptInputMessage))
}
