<script lang="ts">
	import type { Node } from '$lib/realtime';
	import { edgeStore, nodeStore, nodeVisibility } from '$lib/realtime';
	import {
		updateNode,
		compileScript,
		testOrchestration,
		fetchOrchestrationLog,
		aiSuggestScript,
		type CompileScriptResponse,
		type OrchestrationLogEntry
	} from '$lib/api';

	interface Props {
		collection?: Node;
		config: Record<string, unknown>;
		userId?: string;
		accessToken?: string;
	}

	let { collection, config, userId, accessToken }: Props = $props();

	// =========================================================================
	// Orchestration nodes in this collection
	// =========================================================================

	const orchestrationNodes = $derived.by(() => {
		const nodes: Node[] = [];
		if (!collection) return nodes;
		for (const edge of edgeStore.byTarget(collection.id)) {
			if (edge.edgeType !== 'belongs_to') continue;
			const node = nodeStore.get(edge.sourceId);
			if (!node || nodeVisibility(node, userId) === 'hidden') continue;
			if (node.nodeKind === 'orchestration') {
				nodes.push(node);
			}
		}
		nodes.sort((a, b) => (b.createdAt ?? 0) - (a.createdAt ?? 0));
		return nodes;
	});

	// =========================================================================
	// State
	// =========================================================================

	/** Currently selected orchestration node ID */
	let selectedId: string | undefined = $state(undefined);

	/** Auto-select first orchestration node */
	$effect(() => {
		if (!selectedId && orchestrationNodes.length > 0) {
			selectedId = orchestrationNodes[0].id;
		}
	});

	const selectedNode = $derived(selectedId ? nodeStore.get(selectedId) : undefined);

	const selectedMetadata = $derived.by((): Record<string, unknown> => {
		if (!selectedNode?.metadata) return {};
		try {
			return JSON.parse(selectedNode.metadata) as Record<string, unknown>;
		} catch {
			return {};
		}
	});

	// Editor state
	let scriptContent = $state('');
	let activeTab: 'enkel' | 'teknisk' | 'kompilert' = $state('enkel');
	let compileResult = $state<CompileScriptResponse | null>(null);
	let compiling = $state(false);
	let saving = $state(false);
	let testRunning = $state(false);
	let lastTestJobId: string | null = $state(null);

	// Trigger state
	let triggerEvent = $state('manual');
	let triggerConditions = $state('');
	let executor = $state('script');

	// AI-assist
	let showAiAssist = $state(false);
	let aiDescription = $state('');
	let aiGenerating = $state(false);
	let aiError: string | null = $state(null);

	// History
	let logEntries: OrchestrationLogEntry[] = $state([]);
	let showHistory = $state(false);

	// Load content when selected node changes
	$effect(() => {
		if (selectedNode) {
			scriptContent = selectedNode.content ?? '';
			const meta = selectedMetadata;
			const trigger = meta.trigger as Record<string, unknown> | undefined;
			triggerEvent = (trigger?.event as string) ?? 'manual';
			const conditions = trigger?.conditions;
			triggerConditions = conditions ? JSON.stringify(conditions, null, 2) : '';
			executor = (meta.executor as string) ?? 'script';
		}
	});

	// =========================================================================
	// Compile (debounced)
	// =========================================================================

	let compileTimeout: ReturnType<typeof setTimeout> | undefined;

	$effect(() => {
		// React to script changes
		const _content = scriptContent;
		clearTimeout(compileTimeout);
		if (!accessToken || !scriptContent.trim()) {
			compileResult = null;
			return;
		}
		compileTimeout = setTimeout(async () => {
			compiling = true;
			try {
				compileResult = await compileScript(accessToken!, scriptContent);
			} catch (err) {
				console.error('Compile failed:', err);
			} finally {
				compiling = false;
			}
		}, 500);
	});

	// =========================================================================
	// Derived views
	// =========================================================================

	const technicalView = $derived(compileResult?.compiled?.technical ?? '(ingen kompilert utdata)');

	const compiledJson = $derived(
		compileResult?.compiled
			? JSON.stringify(compileResult.compiled, null, 2)
			: '(kompilering feilet eller ingen inndata)'
	);

	const errorCount = $derived(
		compileResult?.diagnostics?.filter((d) => d.severity === 'Error').length ?? 0
	);

	const hasErrors = $derived(errorCount > 0);

	// =========================================================================
	// Actions
	// =========================================================================

	async function save() {
		if (!accessToken || !selectedId) return;
		saving = true;
		try {
			let conditionsObj: Record<string, unknown> | undefined;
			if (triggerConditions.trim()) {
				try {
					conditionsObj = JSON.parse(triggerConditions);
				} catch {
					// Invalid JSON, skip conditions
				}
			}

			const metadata: Record<string, unknown> = {
				...selectedMetadata,
				trigger: {
					event: triggerEvent,
					...(conditionsObj ? { conditions: conditionsObj } : {}),
				},
				executor,
			};

			// Include compiled pipeline if compilation succeeded
			if (compileResult?.compiled) {
				metadata.pipeline = compileResult.compiled.steps;
				if (compileResult.compiled.global_fallback) {
					metadata.global_fallback = compileResult.compiled.global_fallback;
				}
			}

			await updateNode(accessToken, {
				node_id: selectedId,
				content: scriptContent,
				metadata,
			});
		} catch (err) {
			console.error('Save failed:', err);
		} finally {
			saving = false;
		}
	}

	async function runTest() {
		if (!accessToken || !selectedId) return;
		// Save first
		await save();
		testRunning = true;
		try {
			const result = await testOrchestration(accessToken, selectedId);
			lastTestJobId = result.job_id;
		} catch (err) {
			console.error('Test run failed:', err);
		} finally {
			testRunning = false;
		}
	}

	async function loadHistory() {
		if (!accessToken || !selectedId) return;
		try {
			const result = await fetchOrchestrationLog(accessToken, selectedId, 30);
			logEntries = result.entries;
		} catch (err) {
			console.error('Failed to load history:', err);
		}
	}

	function toggleHistory() {
		showHistory = !showHistory;
		if (showHistory) loadHistory();
	}

	async function generateWithAi() {
		if (!accessToken || !aiDescription.trim()) return;
		aiGenerating = true;
		aiError = null;
		try {
			const result = await aiSuggestScript(accessToken, {
				description: aiDescription,
				trigger_event: triggerEvent !== 'manual' ? triggerEvent : undefined,
				collection_id: collection?.id,
			});

			if (result.script) {
				scriptContent = result.script;
				aiDescription = '';
				showAiAssist = false;
			}

			if (result.status === 'generated_with_errors' && result.compile_result) {
				const errors = result.compile_result.diagnostics
					?.filter((d) => d.severity === 'Error')
					.map((d) => d.message)
					.join('; ');
				if (errors) {
					aiError = `Script generert med feil: ${errors}`;
				}
			} else if (result.status === 'deferred') {
				aiError = null;
				showAiAssist = false;
			}
		} catch (err) {
			aiError = err instanceof Error ? err.message : 'Ukjent feil';
		} finally {
			aiGenerating = false;
		}
	}

	// =========================================================================
	// Trigger event options
	// =========================================================================

	const TRIGGER_EVENTS = [
		{ value: 'node.created', label: 'Node opprettet' },
		{ value: 'edge.created', label: 'Edge opprettet' },
		{ value: 'communication.ended', label: 'Samtale avsluttet' },
		{ value: 'node.published', label: 'Node publisert' },
		{ value: 'scheduled.due', label: 'Planlagt tidspunkt' },
		{ value: 'manual', label: 'Manuell' },
	];

	// =========================================================================
	// Helpers
	// =========================================================================

	function formatTime(iso: string): string {
		try {
			const d = new Date(iso);
			return d.toLocaleString('nb-NO', {
				day: 'numeric',
				month: 'short',
				hour: '2-digit',
				minute: '2-digit',
			});
		} catch {
			return iso;
		}
	}
</script>

<div class="orch-trait">
	{#if orchestrationNodes.length === 0}
		<div class="orch-empty">
			<span class="orch-empty-icon">&#9889;</span>
			<p>Ingen orkestreringer i denne samlingen.</p>
			<p class="orch-empty-hint">
				Opprett en orchestration-node for å automatisere arbeidsflyter.
			</p>
		</div>
	{:else}
		<!-- Orchestration selector (if multiple) -->
		{#if orchestrationNodes.length > 1}
			<div class="orch-selector">
				<select
					bind:value={selectedId}
					class="orch-select"
				>
					{#each orchestrationNodes as node (node.id)}
						<option value={node.id}>{node.title ?? 'Uten tittel'}</option>
					{/each}
				</select>
			</div>
		{:else}
			<div class="orch-selector">
				<span class="orch-title">{orchestrationNodes[0]?.title ?? 'Orkestrering'}</span>
			</div>
		{/if}

		<!-- Trigger configuration -->
		<div class="orch-trigger">
			<div class="orch-trigger-row">
				<label class="orch-label" for="trigger-event">Trigger</label>
				<select
					id="trigger-event"
					bind:value={triggerEvent}
					class="orch-select orch-select-sm"
				>
					{#each TRIGGER_EVENTS as evt (evt.value)}
						<option value={evt.value}>{evt.label}</option>
					{/each}
				</select>

				<label class="orch-label" for="executor-select">Executor</label>
				<select
					id="executor-select"
					bind:value={executor}
					class="orch-select orch-select-sm"
				>
					<option value="script">Script</option>
					<option value="bot">Bot</option>
					<option value="dream">Dream</option>
				</select>
			</div>
		</div>

		<!-- Tab bar -->
		<div class="orch-tabs">
			<button
				class="orch-tab"
				class:orch-tab-active={activeTab === 'enkel'}
				onclick={() => { activeTab = 'enkel'; }}
			>
				Enkel
				{#if hasErrors}
					<span class="orch-tab-badge orch-tab-badge-error">{errorCount}</span>
				{/if}
			</button>
			<button
				class="orch-tab"
				class:orch-tab-active={activeTab === 'teknisk'}
				onclick={() => { activeTab = 'teknisk'; }}
			>
				Teknisk
			</button>
			<button
				class="orch-tab"
				class:orch-tab-active={activeTab === 'kompilert'}
				onclick={() => { activeTab = 'kompilert'; }}
			>
				Kompilert
			</button>

			<div class="orch-tab-spacer"></div>

			{#if compiling}
				<span class="orch-status orch-status-compiling">Kompilerer...</span>
			{:else if compileResult && !hasErrors}
				<span class="orch-status orch-status-ok">OK</span>
			{:else if hasErrors}
				<span class="orch-status orch-status-error">{errorCount} feil</span>
			{/if}
		</div>

		<!-- Tab content -->
		<div class="orch-editor-area">
			{#if activeTab === 'enkel'}
				<div class="orch-editor-wrapper">
					<textarea
						class="orch-editor"
						bind:value={scriptContent}
						placeholder={"1. transkriber lydfilen (stor modell)\n   ved feil: transkriber lydfilen (medium modell)\n2. oppsummer samtalen\n\nved feil: opprett oppgave \"Pipeline feilet\" (bug)"}
						spellcheck="false"
					></textarea>

					<!-- Inline diagnostics -->
					{#if compileResult?.diagnostics && compileResult.diagnostics.length > 0}
						<div class="orch-diagnostics">
							{#each compileResult.diagnostics as diag (diag.line + '-' + diag.severity)}
								<div
									class="orch-diag"
									class:orch-diag-ok={diag.severity === 'Ok'}
									class:orch-diag-error={diag.severity === 'Error'}
								>
									<span class="orch-diag-icon">
										{diag.severity === 'Ok' ? '\u2713' : '\u2717'}
									</span>
									<span class="orch-diag-line">L{diag.line}</span>
									{#if diag.severity === 'Ok' && diag.compiled_output}
										<span class="orch-diag-text">{diag.compiled_output}</span>
									{:else if diag.severity === 'Error'}
										<span class="orch-diag-text">{diag.message}</span>
										{#if diag.suggestion}
											<span class="orch-diag-suggestion">Mente du: "{diag.suggestion}"?</span>
										{/if}
									{/if}
								</div>
							{/each}
						</div>
					{/if}
				</div>
			{:else if activeTab === 'teknisk'}
				<pre class="orch-readonly">{technicalView}</pre>
			{:else if activeTab === 'kompilert'}
				<pre class="orch-readonly orch-readonly-json">{compiledJson}</pre>
			{/if}
		</div>

		<!-- AI-assist panel -->
		{#if showAiAssist}
			<div class="orch-ai-panel">
				<div class="orch-ai-header">
					<span class="orch-ai-label">AI-assistent</span>
					<button class="orch-btn-close" onclick={() => { showAiAssist = false; }}>&times;</button>
				</div>
				<textarea
					class="orch-ai-input"
					bind:value={aiDescription}
					placeholder="Beskriv hva orkestreringen skal gjøre..."
					rows="3"
					disabled={aiGenerating}
				></textarea>
				{#if aiError}
					<div class="orch-ai-error">{aiError}</div>
				{/if}
				<div class="orch-ai-actions">
					<button
						class="orch-btn orch-btn-ai"
						onclick={generateWithAi}
						disabled={aiGenerating || !aiDescription.trim()}
					>
						{aiGenerating ? 'Genererer...' : 'Generer script'}
					</button>
				</div>
			</div>
		{/if}

		<!-- Actions -->
		<div class="orch-actions">
			<button
				class="orch-btn orch-btn-primary"
				onclick={save}
				disabled={saving || !accessToken}
			>
				{saving ? 'Lagrer...' : 'Lagre'}
			</button>
			<button
				class="orch-btn orch-btn-test"
				onclick={runTest}
				disabled={testRunning || hasErrors || !accessToken || !scriptContent.trim()}
				title={hasErrors ? 'Rett feilene først' : 'Kjør orkestreringen manuelt'}
			>
				{testRunning ? 'Kjører...' : 'Test kjøring'}
			</button>
			<button
				class="orch-btn orch-btn-ai-toggle"
				onclick={() => { showAiAssist = !showAiAssist; }}
				title="Generer script fra fritekst-beskrivelse med AI"
			>
				{showAiAssist ? 'Skjul AI' : 'AI-assistent'}
			</button>
			<button
				class="orch-btn orch-btn-secondary"
				onclick={toggleHistory}
			>
				{showHistory ? 'Skjul historikk' : 'Historikk'}
			</button>

			{#if lastTestJobId}
				<span class="orch-test-info">Jobb: {lastTestJobId.slice(0, 8)}...</span>
			{/if}
		</div>

		<!-- History panel -->
		{#if showHistory}
			<div class="orch-history">
				<div class="orch-history-header">
					<span>Kjørehistorikk</span>
					<button class="orch-btn-refresh" onclick={loadHistory}>Oppdater</button>
				</div>
				{#if logEntries.length === 0}
					<p class="orch-history-empty">Ingen kjøringer ennå.</p>
				{:else}
					<div class="orch-history-list">
						{#each logEntries as entry (entry.id)}
							<div
								class="orch-history-item"
								class:orch-history-ok={entry.status === 'ok'}
								class:orch-history-error={entry.status === 'error'}
							>
								<span class="orch-history-status">
									{entry.status === 'ok' ? '\u2713' : '\u2717'}
								</span>
								<span class="orch-history-step">
									{#if entry.is_fallback}FB{:else}#{entry.step_number}{/if}
								</span>
								<span class="orch-history-binary">{entry.tool_binary}</span>
								{#if entry.duration_ms != null}
									<span class="orch-history-duration">{entry.duration_ms}ms</span>
								{/if}
								<span class="orch-history-time">{formatTime(entry.created_at)}</span>
								{#if entry.error_msg}
									<div class="orch-history-error-msg">{entry.error_msg}</div>
								{/if}
							</div>
						{/each}
					</div>
				{/if}
			</div>
		{/if}
	{/if}
</div>

<style>
	/* ================================================================= */
	/* Root                                                               */
	/* ================================================================= */
	.orch-trait {
		display: flex;
		flex-direction: column;
		height: 100%;
		min-height: 0;
		overflow: hidden;
		font-size: 13px;
	}

	/* ================================================================= */
	/* Empty state                                                        */
	/* ================================================================= */
	.orch-empty {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		flex: 1;
		padding: 24px;
		color: var(--color-text-dim);
		text-align: center;
		gap: 4px;
	}

	.orch-empty-icon {
		font-size: 28px;
	}

	.orch-empty-hint {
		font-size: 11px;
		color: var(--color-text-muted);
		margin-top: 4px;
	}

	/* ================================================================= */
	/* Selector                                                           */
	/* ================================================================= */
	.orch-selector {
		padding: 8px 12px;
		border-bottom: 1px solid var(--color-border);
		flex-shrink: 0;
	}

	.orch-title {
		font-weight: 600;
		font-size: 14px;
		color: var(--color-text);
	}

	.orch-select {
		width: 100%;
		padding: 4px 8px;
		border: 1px solid var(--color-border);
		border-radius: 4px;
		font-size: 13px;
		background: var(--color-surface);
		color: var(--color-text);
	}

	.orch-select-sm {
		width: auto;
		min-width: 100px;
	}

	/* ================================================================= */
	/* Trigger config                                                     */
	/* ================================================================= */
	.orch-trigger {
		padding: 6px 12px;
		border-bottom: 1px solid var(--color-border);
		flex-shrink: 0;
	}

	.orch-trigger-row {
		display: flex;
		align-items: center;
		gap: 8px;
		flex-wrap: wrap;
	}

	.orch-label {
		font-size: 11px;
		color: var(--color-text-muted);
		text-transform: uppercase;
		letter-spacing: 0.03em;
		white-space: nowrap;
	}

	/* ================================================================= */
	/* Tabs                                                               */
	/* ================================================================= */
	.orch-tabs {
		display: flex;
		align-items: center;
		border-bottom: 1px solid var(--color-border);
		flex-shrink: 0;
		padding: 0 8px;
		gap: 0;
	}

	.orch-tab {
		display: flex;
		align-items: center;
		gap: 4px;
		padding: 8px 12px;
		border: none;
		background: transparent;
		font-size: 12px;
		color: var(--color-text-muted);
		cursor: pointer;
		border-bottom: 2px solid transparent;
		transition: color 0.12s, border-color 0.12s;
	}

	.orch-tab:hover {
		color: var(--color-text-muted);
	}

	.orch-tab-active {
		color: var(--color-accent);
		border-bottom-color: var(--color-accent);
		font-weight: 500;
	}

	.orch-tab-badge {
		font-size: 10px;
		border-radius: 9999px;
		padding: 0 5px;
		line-height: 16px;
	}

	.orch-tab-badge-error {
		background: var(--color-surface);
		color: var(--color-error);
	}

	.orch-tab-spacer {
		flex: 1;
	}

	.orch-status {
		font-size: 11px;
		padding: 2px 8px;
		border-radius: 9999px;
		white-space: nowrap;
	}

	.orch-status-compiling {
		color: var(--color-text-muted);
		background: var(--color-surface-hover);
	}

	.orch-status-ok {
		color: var(--color-success);
		background: var(--color-surface);
	}

	.orch-status-error {
		color: var(--color-error);
		background: var(--color-surface);
	}

	/* ================================================================= */
	/* Editor area                                                        */
	/* ================================================================= */
	.orch-editor-area {
		flex: 1;
		min-height: 0;
		overflow: auto;
		display: flex;
		flex-direction: column;
	}

	.orch-editor-wrapper {
		display: flex;
		flex-direction: column;
		flex: 1;
		min-height: 0;
	}

	.orch-editor {
		flex: 1;
		min-height: 120px;
		padding: 10px 12px;
		border: none;
		resize: none;
		font-family: 'JetBrains Mono', 'Fira Code', monospace;
		font-size: 13px;
		line-height: 1.5;
		color: var(--color-text);
		background: var(--color-bg);
		outline: none;
	}

	.orch-editor::placeholder {
		color: var(--color-text-muted);
	}

	.orch-readonly {
		flex: 1;
		margin: 0;
		padding: 10px 12px;
		font-family: 'JetBrains Mono', 'Fira Code', monospace;
		font-size: 12px;
		line-height: 1.5;
		color: var(--color-text-muted);
		background: var(--color-bg);
		border: none;
		overflow: auto;
		white-space: pre-wrap;
		word-break: break-word;
	}

	.orch-readonly-json {
		font-size: 11px;
		color: var(--color-text-dim);
	}

	/* ================================================================= */
	/* Diagnostics                                                        */
	/* ================================================================= */
	.orch-diagnostics {
		border-top: 1px solid var(--color-border);
		padding: 6px 8px;
		display: flex;
		flex-direction: column;
		gap: 3px;
		max-height: 160px;
		overflow-y: auto;
		background: var(--color-surface);
		flex-shrink: 0;
	}

	.orch-diag {
		display: flex;
		align-items: baseline;
		gap: 6px;
		font-size: 11px;
		line-height: 1.4;
		flex-wrap: wrap;
	}

	.orch-diag-icon {
		flex-shrink: 0;
		font-weight: 700;
	}

	.orch-diag-ok .orch-diag-icon {
		color: var(--color-success);
	}

	.orch-diag-error .orch-diag-icon {
		color: var(--color-error);
	}

	.orch-diag-line {
		font-size: 10px;
		color: var(--color-text-dim);
		font-variant-numeric: tabular-nums;
		flex-shrink: 0;
	}

	.orch-diag-text {
		color: var(--color-text-muted);
	}

	.orch-diag-error .orch-diag-text {
		color: var(--color-error);
	}

	.orch-diag-suggestion {
		color: var(--color-accent);
		font-style: italic;
	}

	/* ================================================================= */
	/* Actions                                                            */
	/* ================================================================= */
	.orch-actions {
		display: flex;
		align-items: center;
		gap: 8px;
		padding: 8px 12px;
		border-top: 1px solid var(--color-border);
		flex-shrink: 0;
		flex-wrap: wrap;
	}

	.orch-btn {
		padding: 5px 12px;
		border: 1px solid var(--color-border);
		border-radius: 5px;
		font-size: 12px;
		font-weight: 500;
		cursor: pointer;
		transition: background 0.1s, opacity 0.1s;
	}

	.orch-btn:disabled {
		opacity: 0.5;
		cursor: not-allowed;
	}

	.orch-btn-primary {
		background: var(--color-accent);
		color: white;
		border-color: var(--color-accent);
	}

	.orch-btn-primary:hover:not(:disabled) {
		background: var(--color-accent-hover);
	}

	.orch-btn-test {
		background: var(--color-success);
		color: white;
		border-color: var(--color-success);
	}

	.orch-btn-test:hover:not(:disabled) {
		background: var(--color-success);
	}

	.orch-btn-secondary {
		background: var(--color-surface);
		color: var(--color-text-muted);
	}

	.orch-btn-secondary:hover:not(:disabled) {
		background: var(--color-surface-hover);
	}

	.orch-test-info {
		font-size: 11px;
		color: var(--color-text-muted);
		font-family: monospace;
	}

	/* ================================================================= */
	/* History panel                                                      */
	/* ================================================================= */
	.orch-history {
		border-top: 1px solid var(--color-border);
		max-height: 240px;
		overflow-y: auto;
		background: var(--color-bg);
		flex-shrink: 0;
	}

	.orch-history-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 6px 12px;
		font-size: 11px;
		font-weight: 600;
		color: var(--color-text-muted);
		border-bottom: 1px solid var(--color-border);
		position: sticky;
		top: 0;
		background: var(--color-bg);
	}

	.orch-btn-refresh {
		padding: 2px 8px;
		border: 1px solid var(--color-border);
		border-radius: 3px;
		font-size: 10px;
		background: var(--color-surface);
		cursor: pointer;
		color: var(--color-text-dim);
	}

	.orch-btn-refresh:hover {
		background: var(--color-surface-hover);
	}

	.orch-history-empty {
		padding: 12px;
		text-align: center;
		color: var(--color-text-dim);
		font-size: 12px;
	}

	.orch-history-list {
		display: flex;
		flex-direction: column;
	}

	.orch-history-item {
		display: flex;
		align-items: center;
		gap: 8px;
		padding: 5px 12px;
		font-size: 11px;
		border-bottom: 1px solid var(--color-border);
		flex-wrap: wrap;
	}

	.orch-history-status {
		flex-shrink: 0;
		font-weight: 700;
		width: 14px;
		text-align: center;
	}

	.orch-history-ok .orch-history-status {
		color: var(--color-success);
	}

	.orch-history-error .orch-history-status {
		color: var(--color-error);
	}

	.orch-history-step {
		font-size: 10px;
		color: var(--color-text-muted);
		font-variant-numeric: tabular-nums;
		min-width: 20px;
	}

	.orch-history-binary {
		font-family: monospace;
		font-size: 11px;
		color: var(--color-text);
	}

	.orch-history-duration {
		font-size: 10px;
		color: var(--color-text-dim);
		font-variant-numeric: tabular-nums;
	}

	.orch-history-time {
		font-size: 10px;
		color: var(--color-text-dim);
		margin-left: auto;
	}

	.orch-history-error-msg {
		width: 100%;
		padding: 3px 0 3px 22px;
		font-size: 10px;
		color: var(--color-error);
		word-break: break-word;
	}

	/* ================================================================= */
	/* AI-assist panel                                                    */
	/* ================================================================= */
	.orch-ai-panel {
		border-top: 1px solid var(--color-border);
		padding: 8px 12px;
		background: var(--color-surface);
		display: flex;
		flex-direction: column;
		gap: 6px;
		flex-shrink: 0;
	}

	.orch-ai-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
	}

	.orch-ai-label {
		font-size: 11px;
		font-weight: 600;
		color: var(--color-accent);
		text-transform: uppercase;
		letter-spacing: 0.03em;
	}

	.orch-btn-close {
		border: none;
		background: transparent;
		font-size: 16px;
		color: var(--color-text-muted);
		cursor: pointer;
		padding: 0 4px;
		line-height: 1;
	}

	.orch-btn-close:hover {
		color: var(--color-text);
	}

	.orch-ai-input {
		width: 100%;
		padding: 6px 8px;
		border: 1px solid var(--color-accent);
		border-radius: 4px;
		font-size: 13px;
		font-family: inherit;
		resize: vertical;
		min-height: 48px;
		background: var(--color-surface);
		color: var(--color-text);
	}

	.orch-ai-input::placeholder {
		color: var(--color-accent);
	}

	.orch-ai-input:focus {
		outline: none;
		border-color: var(--color-accent);
		box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.1);
	}

	.orch-ai-error {
		font-size: 11px;
		color: var(--color-error);
		background: var(--color-surface);
		padding: 4px 8px;
		border-radius: 3px;
	}

	.orch-ai-actions {
		display: flex;
		gap: 6px;
	}

	.orch-btn-ai {
		background: var(--color-accent);
		color: white;
		border-color: var(--color-accent);
	}

	.orch-btn-ai:hover:not(:disabled) {
		background: var(--color-accent-hover);
	}

	.orch-btn-ai-toggle {
		background: var(--color-surface);
		color: var(--color-accent);
		border-color: var(--color-accent);
	}

	.orch-btn-ai-toggle:hover:not(:disabled) {
		background: var(--color-surface-hover);
	}

	/* ================================================================= */
	/* Responsive                                                         */
	/* ================================================================= */
	@container (max-width: 400px) {
		.orch-trigger-row {
			flex-direction: column;
			align-items: stretch;
			gap: 4px;
		}

		.orch-select-sm {
			width: 100%;
		}

		.orch-actions {
			flex-direction: column;
			align-items: stretch;
		}

		.orch-btn {
			width: 100%;
			text-align: center;
		}

		.orch-test-info {
			text-align: center;
		}
	}

	@media (max-width: 480px) {
		.orch-trigger-row {
			flex-direction: column;
			align-items: stretch;
			gap: 4px;
		}

		.orch-select-sm {
			width: 100%;
		}

		.orch-editor {
			min-height: 100px;
			font-size: 12px;
		}
	}
</style>
