import { computed, type Ref } from 'vue';
import { projectToolRender } from '../tools/renderer-registry';
import type { ChatMessage, SessionTreeEntry, StreamingToolProjection } from '../types/index.d';

type ChatStreamingDisplayRefs = {
	loading: Ref<boolean>;
	pendingUserContent: Ref<string>;
	streamingAssistantEntryId: Ref<string | null>;
	streamingAssistantText: Ref<string>;
	streamingAssistantThinking: Ref<string>;
	streamingTools: Ref<StreamingToolProjection[]>;
	streamingError: Ref<string>;
	visibleConversationEntries: Ref<SessionTreeEntry[]>;
};

export function useChatStreamingDisplay(refs: ChatStreamingDisplayRefs) {
	const streamingParsed = computed(() => {
		const source = refs.streamingAssistantText.value || '';
		const match = source.match(/<think>([\s\S]*?)<\/think>/i);
		const extractedThinking = match?.[1]?.trim() || '';
		const content = match ? source.replace(match[0], '').trimStart() : source;

		return {
			thinking: (refs.streamingAssistantThinking.value || extractedThinking).trim(),
			content,
		};
	});

	const pendingUserMessage = computed<ChatMessage | null>(() => {
		if (!refs.loading.value || !refs.pendingUserContent.value) return null;
		return {
			role: 'user',
			content: refs.pendingUserContent.value,
			createTime: '',
		};
	});

	const streamingMessage = computed<ChatMessage>(() => {
		return {
			role: 'assistant',
			content: streamingParsed.value.content,
			createTime: '',
		};
	});

	const streamingThinkingDisplay = computed(() => streamingParsed.value.thinking);

	const visibleStreamingTools = computed(() => {
		return refs.streamingTools.value.map(tool => ({
			...projectToolRender({
				toolCallId: tool.toolCallId,
				toolName: tool.toolName,
				label: tool.label,
				args: tool.args,
				result: tool.result,
				rawResult: tool.rawResult,
				status: tool.status,
			}),
			runtimeRoute: tool.runtimeRoute,
			workerRoutingHint: tool.workerRoutingHint,
			blockedReason: tool.blockedReason,
			policySources: tool.policySources,
			latestProcessEvent: tool.latestProcessEvent,
			processEvents: tool.processEvents,
			processLogRef: tool.processLogRef,
		}));
	});

	const hasFinalStreamingAssistantEntry = computed(() => {
		const entryId = refs.streamingAssistantEntryId.value;
		return Boolean(entryId && refs.visibleConversationEntries.value.some(entry => entry.id === entryId && entry.message?.content));
	});

	const hasStreamingStatusContent = computed(() => Boolean(
		visibleStreamingTools.value.length ||
		refs.streamingError.value
	));

	const shouldShowStreamingMessage = computed(() => Boolean(
		streamingMessage.value.content &&
		(refs.loading.value || !hasFinalStreamingAssistantEntry.value)
	));

	const shouldShowStreamingStatus = computed(() => Boolean(
		pendingUserMessage.value ||
		shouldShowStreamingMessage.value ||
		streamingThinkingDisplay.value ||
		(hasStreamingStatusContent.value && (refs.loading.value || !hasFinalStreamingAssistantEntry.value))
	));

	function shouldShowStreamingToolRuntimeMeta(tool: { toolName?: string; runtimeRoute?: string; workerRoutingHint?: string; blockedReason?: string | null }) {
		const name = tool.toolName || '';
		if (name === 'delegate_task' || name === 'delegate_parallel' || name === 'todo') {
			return false;
		}
		return Boolean(tool.runtimeRoute || tool.workerRoutingHint || tool.blockedReason);
	}

	return {
		hasStreamingStatusContent,
		pendingUserMessage,
		shouldShowStreamingMessage,
		shouldShowStreamingStatus,
		shouldShowStreamingToolRuntimeMeta,
		streamingMessage,
		streamingParsed,
		streamingThinkingDisplay,
		visibleStreamingTools,
	};
}
