import type { ChatMessage, SessionHistoryPayload, ToolCallBlock } from "../types/message";
import { nextMessageId } from "./format";
import {
	extractContent,
	extractImages,
	extractThinking,
	formatToolCall,
	formatToolResult,
	getToolCalls,
	upsertToolCallMessage,
} from "./toolCall";

function appendAssistantBlocks(m: { content?: string | unknown[] }, result: ChatMessage[]): void {
	if (Array.isArray(m.content)) {
		for (const block of m.content) {
			const b = block as { type?: string; thinking?: string; text?: string };
			if (b.type === "thinking") {
				const thinking = (b.thinking ?? "").trim();
				if (thinking) {
					result.push({ id: nextMessageId(), role: "thinking", content: thinking });
				}
			} else if (b.type === "text") {
				const text = (b.text ?? "").trim();
				if (text) {
					const last = result[result.length - 1];
					if (last?.role === "assistant") {
						last.content += text;
					} else {
						result.push({ id: nextMessageId(), role: "assistant", content: text });
					}
				}
			} else if (b.type === "toolCall") {
				const tc = block as ToolCallBlock;
				const tid = tc.toolCallId || tc.id;
				const tidStr = tid ? String(tid) : undefined;
				upsertToolCallMessage(result, {
					id: tidStr ? `tool-${tidStr}` : nextMessageId(),
					role: "tool_call",
					content: formatToolCall(tc),
					toolCallId: tidStr,
				});
			}
		}
		return;
	}
	const text = extractContent(m.content as string | undefined);
	if (text) {
		result.push({ id: nextMessageId(), role: "assistant", content: text });
	}
	for (const tc of getToolCalls(m.content as string | undefined)) {
		const tid = tc.toolCallId || tc.id;
		const tidStr = tid ? String(tid) : undefined;
		upsertToolCallMessage(result, {
			id: tidStr ? `tool-${tidStr}` : nextMessageId(),
			role: "tool_call",
			content: formatToolCall(tc),
			toolCallId: tidStr,
		});
	}
}

export function buildHistoryMessages(payload: SessionHistoryPayload): ChatMessage[] {
	const result: ChatMessage[] = [];
	for (const m of payload.messages || []) {
		if (m.role === "user") {
			const text = extractContent(m.content);
			const images = extractImages(m.content);
			if (text || images.length) {
				result.push({
					id: nextMessageId(),
					role: "user",
					content: text,
					...(images.length ? { images } : {}),
				});
			}
		} else if (m.role === "assistant") {
			appendAssistantBlocks(m, result);
		} else if (m.role === "toolResult" || m.role === "tool") {
			const text = formatToolResult({ content: m.content });
			if (text.trim()) {
				const tid = m.toolCallId ? String(m.toolCallId) : undefined;
				upsertToolCallMessage(result, {
					id: tid ? `tool-${tid}` : nextMessageId(),
					role: "tool_call",
					content: `✅ tool\n${text}`,
					toolCallId: tid,
				});
			}
		} else if (m.role === "bashExecution") {
			const output = typeof m.output === "string" ? m.output : "";
			result.push({
				id: nextMessageId(),
				role: "user",
				content: m.excludeFromContext ? `!!${m.command}` : `!${m.command}`,
			});
			result.push({
				id: nextMessageId(),
				role: "bash",
				content: output,
				bashCommand: m.command,
				bashExitCode: m.exitCode,
				bashExcludeFromContext: m.excludeFromContext,
			});
		} else if (m.role === "compactionSummary") {
			const summary = typeof m.summary === "string" ? m.summary : extractContent(m.content);
			if (summary.trim()) {
				result.push({ id: nextMessageId(), role: "compaction_summary", content: summary });
			}
		} else if (m.role === "branchSummary") {
			const summary = typeof m.summary === "string" ? m.summary : extractContent(m.content);
			if (summary.trim()) {
				result.push({ id: nextMessageId(), role: "branch_summary", content: summary });
			}
		}
	}
	return result;
}

export function extractThinkingFromMessage(m: { content?: string | unknown[] }): string {
	return extractThinking(m.content as string | undefined);
}
