import type { SegmentedConversationMessage } from "../../../contracts";
import type { DecisionSignals, SmartDecisionInput } from "./types";

const MESSAGE_CHAR_LIMIT = 220;

function normalizeText(text: string): string {
	return text.replace(/\s+/g, " ").trim();
}

function clipText(text: string, maxChars: number): string {
	const normalized = normalizeText(text);
	if (normalized.length <= maxChars) {
		return normalized;
	}
	return `${normalized.slice(0, Math.max(0, maxChars - 3))}...`;
}

function formatPromptMessage(message: SegmentedConversationMessage): string {
	const senderPrefix =
		message.senderType === "visitor"
			? "[VISITOR]"
			: message.senderType === "human_agent"
				? "[TEAM]"
				: "[AI]";
	const visibilityPrefix =
		message.visibility === "private" ? "[PRIVATE]" : "[PUBLIC]";

	return `- ${senderPrefix}${visibilityPrefix} ${clipText(message.content, MESSAGE_CHAR_LIMIT)}`;
}

function formatSection(
	label: string,
	messages: SegmentedConversationMessage[]
): string {
	if (messages.length === 0) {
		return `${label}:\n- (none)`;
	}

	return `${label}:\n${messages.map(formatPromptMessage).join("\n")}`;
}

export function buildSmartDecisionPrompt(
	input: SmartDecisionInput,
	signals: DecisionSignals
): string {
	const beforeTrigger = input.decisionMessages.filter(
		(message) => message.segment === "before_trigger"
	);
	const currentTrigger = input.decisionMessages.filter(
		(message) => message.segment === "trigger"
	);
	const afterTrigger = input.decisionMessages.filter(
		(message) => message.segment === "after_trigger"
	);

	return `You are the decision gate for a support AI.

Pick one intent:
- respond: AI should take this turn now
- observe: AI should not act this turn
- assist_team: internal/private help only (no visitor-facing message)

Intent guidance:
- For visitor triggers, "respond" means reply to the visitor.
- For human-agent triggers, "respond" means execute the teammate's request (can be public or private as needed).
- "assist_team" means leave internal guidance only.

Timeline semantics:
- "Current Trigger" is the queued message being processed in FIFO order.
- "Later Context" contains newer messages that happened after the trigger.
- Use Later Context for awareness so you avoid redundant, mistimed, or contradictory replies.
- Do not switch triggers; decide whether AI should act for the Current Trigger with full awareness of Later Context.

Decision policy (from decision.md):
${input.decisionPolicy}

Signals:
- triggerSender=${input.triggerMessage.senderType}
- triggerVisibility=${input.triggerMessage.visibility}
- triggerLooksLikeHumanCommand=${signals.triggerLooksLikeHumanCommand}
- triggerIsQuestionOrRequest=${signals.triggerIsQuestionOrRequest}
- humanActive=${signals.humanActive}
- lastHumanSecondsAgo=${signals.lastHumanSecondsAgo ?? "none"}
- messagesSinceHuman=${signals.messagesSinceHuman >= 0 ? signals.messagesSinceHuman : "none"}
- hasHumanAssignee=${input.conversationState.hasHumanAssignee}
- escalated=${input.conversationState.isEscalated}
- visitorBurst=${signals.visitorBurstCount}
- recentTurns=${signals.recentTurnPattern || "none"}
- hasLaterHumanMessage=${signals.hasLaterHumanMessage}
- hasLaterAiMessage=${signals.hasLaterAiMessage}

${formatSection("Before Trigger", beforeTrigger)}

${formatSection("Current Trigger", currentTrigger)}

${formatSection("Later Context", afterTrigger)}

Return concise reasoning (max 1 sentence).`;
}
