// Package promptcompiler renders runtime prompt bundles for AgentTeam agent turns.
// This file holds the shared glue: template path constants, section joining,
// template rendering, and the small value-extraction helpers used across the
// per-slot files (text_*.go) in this package.
package promptcompiler

import (
	"encoding/json"
	"strings"
)

const (
	templateAgentAgentsDoc                 = "agent/agents_doc.md"
	templateAgentInitialRole               = "agent/initial_role.md"
	templateEventCurrentMessage            = "events/current_message.md"
	templateWorkflowAgentEdit              = "events/workflow_edit.md"
	templateTaskDispatch                   = "events/task_dispatch.md"
	templateReactionDetails                = "events/reaction_details.md"
	templateMessageDetails                 = "events/message_details.md"
	templateAttachmentDetails              = "events/attachment_details.md"
	templateThreadRoot                     = "events/thread_root.md"
	templateTaskScopeContext               = "events/task_scope_context.md"
	templateDeliveryHeader                 = "events/delivery_header.md"
	templateWorkflowTeamContext            = "events/workflow_team_context.md"
	templateEventDeferredContinuation      = "events/deferred_continuation.md"
	templateEventDeliveryMessage           = "events/delivery_message.md"
	templateMemoryResumeReminder           = "events/memory_resume_reminder.md"
	templateEventResumeIdle                = "events/resume_idle.md"
	templateEventUnreadSummary             = "events/unread_summary.md"
	templateEventWakeMessage               = "events/wake_message.md"
	templatePlatformCooperation            = "platform/cooperation.md"
	templatePlatformIdentity               = "platform/identity.md"
	templatePlatformAgentTeamReviewContext = "platform/agentteam/review_context.md"
	templatePlatformAgentTeamStartup       = "platform/agentteam/startup.md"
	templatePlatformAgentTeamTaskBoards    = "platform/agentteam/task_boards.md"
	templatePlatformRemoteMemory           = "platform/remote_memory.md"
	templatePlatformAgentIdentity          = "platform/agent_identity.md"
	templatePlatformWhoYouAre              = "platform/who_you_are.md"
	templatePlatformWorkspaceMemory        = "platform/workspace_memory.md"
)

func joinPromptSections(parts ...string) string {
	trimmed := make([]string, 0, len(parts))
	for _, part := range parts {
		if section := strings.TrimSpace(part); section != "" {
			trimmed = append(trimmed, section)
		}
	}
	return strings.Join(trimmed, "\n\n")
}

func promptStringMapValue(values map[string]any, key string) string {
	raw, ok := values[key]
	if !ok {
		return ""
	}
	text, ok := raw.(string)
	if !ok {
		return ""
	}
	return strings.TrimSpace(text)
}

func promptIntMapValue(values map[string]any, key string) (int64, bool) {
	raw, ok := values[key]
	if !ok || raw == nil {
		return 0, false
	}
	switch value := raw.(type) {
	case int:
		return int64(value), true
	case int32:
		return int64(value), true
	case int64:
		return value, true
	case float64:
		return int64(value), true
	case json.Number:
		number, err := value.Int64()
		if err != nil {
			return 0, false
		}
		return number, true
	default:
		return 0, false
	}
}

func promptStringSliceMapValue(values map[string]any, key string) []string {
	raw, ok := values[key]
	if !ok || raw == nil {
		return nil
	}
	switch items := raw.(type) {
	case []string:
		out := make([]string, 0, len(items))
		for _, item := range items {
			if text := strings.TrimSpace(item); text != "" {
				out = append(out, text)
			}
		}
		return out
	case []any:
		out := make([]string, 0, len(items))
		for _, item := range items {
			text, ok := item.(string)
			if !ok {
				continue
			}
			if text = strings.TrimSpace(text); text != "" {
				out = append(out, text)
			}
		}
		return out
	default:
		return nil
	}
}

func promptTrimRunes(text string, maxRunes int) string {
	text = strings.TrimSpace(text)
	if text == "" || maxRunes <= 0 {
		return text
	}
	runes := []rune(text)
	if len(runes) <= maxRunes {
		return text
	}
	return strings.TrimSpace(string(runes[:maxRunes])) + "..."
}
