<script lang="ts">
	import type { SubagentResult } from '$lib/proto/llm_multiverse/v1/common_pb';
	import { ResultStatus, ResultQuality, ArtifactType } from '$lib/proto/llm_multiverse/v1/common_pb';
	import { resultSourceConfig } from '$lib/types/resultSource';

	let { result }: { result: SubagentResult } = $props();

	const statusConfig = $derived.by(() => {
		switch (result.status) {
			case ResultStatus.SUCCESS:
				return { label: 'Success', bg: 'bg-green-100 dark:bg-green-900/30', text: 'text-green-800 dark:text-green-300', border: 'border-green-200 dark:border-green-800' };
			case ResultStatus.PARTIAL:
				return { label: 'Partial', bg: 'bg-amber-100 dark:bg-amber-900/30', text: 'text-amber-800 dark:text-amber-300', border: 'border-amber-200 dark:border-amber-800' };
			case ResultStatus.FAILED:
				return { label: 'Failed', bg: 'bg-red-100 dark:bg-red-900/30', text: 'text-red-800 dark:text-red-300', border: 'border-red-200 dark:border-red-800' };
			default:
				return { label: 'Unknown', bg: 'bg-gray-100 dark:bg-gray-800', text: 'text-gray-800 dark:text-gray-300', border: 'border-gray-200 dark:border-gray-700' };
		}
	});

	const qualityLabel = $derived.by(() => {
		switch (result.resultQuality) {
			case ResultQuality.VERIFIED: return 'Verified';
			case ResultQuality.INFERRED: return 'Inferred';
			case ResultQuality.UNCERTAIN: return 'Uncertain';
			default: return '';
		}
	});

	const sourceBadge = $derived(resultSourceConfig(result.source));

	const LINE_COLLAPSE_THRESHOLD = 20;

	function contentLineCount(content: string): number {
		return content.split('\n').length;
	}

	const URL_RE = /(https?:\/\/[^\s<>"')\]]+)/g;

	function linkify(text: string): string {
		return text.replace(URL_RE, '<a href="$1" target="_blank" rel="noopener noreferrer" class="text-blue-600 dark:text-blue-400 underline hover:text-blue-800 dark:hover:text-blue-300 break-all">$1</a>');
	}

	let copiedIndex: number | null = $state(null);

	async function copyToClipboard(content: string, index: number) {
		await navigator.clipboard.writeText(content);
		copiedIndex = index;
		setTimeout(() => {
			if (copiedIndex === index) copiedIndex = null;
		}, 2000);
	}
</script>

<details class="mx-4 mb-3 rounded-xl border {statusConfig.border} {statusConfig.bg}">
	<summary class="flex cursor-pointer items-center gap-2 px-4 py-2.5 select-none">
		<svg class="chevron h-4 w-4 shrink-0 text-gray-500 dark:text-gray-400 transition-transform" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5" /></svg>
		<span class="rounded-full px-2.5 py-0.5 text-xs font-medium {statusConfig.bg} {statusConfig.text}">
			{statusConfig.label}
		</span>
		{#if qualityLabel}
			<span class="rounded-full bg-blue-100 dark:bg-blue-900/40 px-2.5 py-0.5 text-xs font-medium text-blue-800 dark:text-blue-300">
				{qualityLabel}
			</span>
		{/if}
		{#if sourceBadge.label !== 'Unspecified'}
			<span class="rounded-full {sourceBadge.bg} px-2.5 py-0.5 text-xs font-medium {sourceBadge.text}">
				{sourceBadge.label}
			</span>
		{/if}
		{#if result.summary}
			<span class="ml-1 truncate text-xs {statusConfig.text}">{result.summary}</span>
		{/if}
	</summary>

	<div class="max-h-96 overflow-y-auto border-t {statusConfig.border} px-4 pb-4 pt-3">
		{#if result.summary}
			<p class="text-sm {statusConfig.text}">{@html linkify(result.summary)}</p>
		{/if}

		{#if result.failureReason}
			<p class="mt-2 text-sm text-red-700 dark:text-red-400">Reason: {result.failureReason}</p>
		{/if}

		{#if result.artifacts.length > 0}
			<div class="mt-3 border-t {statusConfig.border} pt-3">
				<p class="mb-1.5 text-xs font-medium text-gray-600 dark:text-gray-400">Artifacts</p>
				<div class="space-y-3">
					{#each result.artifacts as artifact, i (artifact.label + i)}
						{#if artifact.artifactType === ArtifactType.CODE}
							<!-- Code artifact: syntax-highlighted block with filename header -->
							<div class="rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden">
								<div class="flex items-center gap-2 bg-gray-100 dark:bg-gray-800 px-3 py-1.5 text-xs">
									<span class="text-blue-600 dark:text-blue-400">&#128196;</span>
									<span class="font-mono font-medium text-gray-700 dark:text-gray-300">{artifact.label}</span>
									<div class="ml-auto flex items-center gap-1.5">
										{#if artifact.metadata?.language}
											<span class="rounded bg-gray-200 dark:bg-gray-700 px-1.5 py-0.5 text-[10px] text-gray-500 dark:text-gray-400">{artifact.metadata.language}</span>
										{/if}
										<button
											type="button"
											onclick={() => copyToClipboard(artifact.content, i)}
											class="rounded p-0.5 text-gray-400 hover:bg-gray-200 hover:text-gray-600 dark:text-gray-500 dark:hover:bg-gray-700 dark:hover:text-gray-300 transition-colors"
											title="Copy code"
										>
											{#if copiedIndex === i}
												<svg class="h-3.5 w-3.5 text-green-500" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" /></svg>
											{:else}
												<svg class="h-3.5 w-3.5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.666 3.888A2.25 2.25 0 0 0 13.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 0 1-.75.75H9.75a.75.75 0 0 1-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 0 1-2.25 2.25H6.75A2.25 2.25 0 0 1 4.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 0 1 1.927-.184" /></svg>
											{/if}
										</button>
									</div>
								</div>
								{#if contentLineCount(artifact.content) > LINE_COLLAPSE_THRESHOLD}
									<details>
										<summary class="cursor-pointer bg-gray-50 dark:bg-gray-900 px-3 py-1 text-xs text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300">
											Show {contentLineCount(artifact.content)} lines
										</summary>
										<pre class="overflow-x-auto bg-gray-50 dark:bg-gray-900 p-3 text-xs leading-relaxed text-gray-800 dark:text-gray-200"><code class="language-{artifact.metadata?.language ?? ''}">{artifact.content}</code></pre>
									</details>
								{:else}
									<pre class="overflow-x-auto bg-gray-50 dark:bg-gray-900 p-3 text-xs leading-relaxed text-gray-800 dark:text-gray-200"><code class="language-{artifact.metadata?.language ?? ''}">{artifact.content}</code></pre>
								{/if}
							</div>

						{:else if artifact.artifactType === ArtifactType.COMMAND_OUTPUT}
							<!-- Command output: terminal-style block -->
							<div class="rounded-lg border border-gray-700 dark:border-gray-600 overflow-hidden">
								<div class="flex items-center gap-2 bg-gray-800 dark:bg-gray-900 px-3 py-1.5 text-xs">
									<span class="text-green-400">&#9654;</span>
									<span class="font-mono text-gray-300">{artifact.label}</span>
								</div>
								{#if contentLineCount(artifact.content) > LINE_COLLAPSE_THRESHOLD}
									<details>
										<summary class="cursor-pointer bg-gray-900 dark:bg-black px-3 py-1 text-xs text-gray-400 hover:text-gray-200">
											Show {contentLineCount(artifact.content)} lines
										</summary>
										<pre class="overflow-x-auto bg-gray-900 dark:bg-black p-3 font-mono text-xs leading-relaxed text-green-300 dark:text-green-400">{artifact.content}</pre>
									</details>
								{:else}
									<pre class="overflow-x-auto bg-gray-900 dark:bg-black p-3 font-mono text-xs leading-relaxed text-green-300 dark:text-green-400">{artifact.content}</pre>
								{/if}
							</div>

						{:else if artifact.artifactType === ArtifactType.SEARCH_RESULT}
							<!-- Search result: card with query title -->
							<div class="rounded-lg border border-purple-200 dark:border-purple-800 bg-purple-50 dark:bg-purple-900/20 p-3">
								<div class="mb-1 flex items-center gap-2 text-xs">
									<span class="text-purple-500">&#128269;</span>
									<span class="font-medium text-purple-700 dark:text-purple-300">{artifact.label}</span>
								</div>
								{#if contentLineCount(artifact.content) > LINE_COLLAPSE_THRESHOLD}
									<details>
										<summary class="cursor-pointer text-xs text-purple-500 dark:text-purple-400 hover:text-purple-700 dark:hover:text-purple-300">
											Show full results
										</summary>
										<p class="mt-1 whitespace-pre-wrap text-xs text-gray-700 dark:text-gray-300">{@html linkify(artifact.content)}</p>
									</details>
								{:else}
									<p class="whitespace-pre-wrap text-xs text-gray-700 dark:text-gray-300">{@html linkify(artifact.content)}</p>
								{/if}
							</div>

						{:else}
							<!-- Text / finding artifact: plain text -->
							<div class="flex items-start gap-2 text-sm">
								<span class="mt-0.5 text-gray-400 dark:text-gray-500">&#128196;</span>
								<span class="text-xs text-gray-700 dark:text-gray-300">{@html linkify(artifact.content)}</span>
							</div>
						{/if}
					{/each}
				</div>
			</div>
		{/if}
	</div>
</details>

<style>
	details[open] > summary .chevron {
		transform: rotate(90deg);
	}
</style>
