<!-- #region TranslationRunResult [C:3] [TYPE Component] [SEMANTICS translate, result, stats, retry, sql-audit, metrics, bulk-replace] -->
<!-- @ingroup Translate -->
<!-- @BRIEF Run result detail panel: statistics grid, per-language breakdown with token/cost, collapsible batch history with per-batch duration, collapsible records table with load-all and inline bulk-replace, SQL audit, retry actions, and correction cells. -->
<!-- @RELATION DEPENDS_ON -> [TranslateApi] -->
<!-- @RELATION DEPENDS_ON -> [BulkReplaceModal] -->
<!-- @RELATION DEPENDS_ON -> [EXT:frontend:api_module] -->
<!-- @UX_STATE completed -> All phases completed, full stats displayed -->
<!-- @UX_STATE partial -> Translation completed with failures, retry available -->
<!-- @UX_STATE failed -> Translation failed, retry available -->
<!-- @UX_STATE insert_failed -> Insert phase failed, retry-insert available -->
<!-- @UX_FEEDBACK Tabular statistics; per-language token count and estimated cost; collapsible batch breakdown with per-batch duration -->
<!-- @UX_FEEDBACK click to copy Superset query ID; collapsible SQL block. -->
<!-- @UX_FEEDBACK Records table with deduplicate by source_hash (NOT EXISTS subquery), "Load more" button (page_size: 50, paginated), and "Bulk Replace" button. Source cell shows text + key values from source_data. -->
<!-- @UX_RECOVERY Retry failed batches; retry insert. -->
<script lang="ts">
import { SvelteSet } from "svelte/reactivity";
	import { getT } from '$lib/i18n/index.svelte.js';
	import { addToast } from '$lib/toasts.svelte.js';
	import {
		fetchRunStatus,
		fetchRunRecords,
		fetchRunBatches,
		retryFailedBatches,
		retryInsert,
		downloadFailedCsv
	} from '$lib/api/translate.js';
	import CorrectionCell from './CorrectionCell.svelte';
	import TermCorrectionPopup from './TermCorrectionPopup.svelte';
	import BulkReplaceModal from './BulkReplaceModal.svelte';

	/** @type {{ runId: string, onRefresh: Function }} */
	let { runId, onRefresh = () => {} } = $props();

	/**
	 * @type {'completed'|'partial'|'failed'|'insert_failed'}
	 */
	let uxState = $state('completed');
  // @RATIONALE Svelte 5 store detection fails for `$t` in deeply nested templates.
  //             Use getT() + $derived to keep reactivity to locale changes.
  const _t = $derived(getT());
	let status = $state(null);
	let records = $state([]);
	let showRecords = $state(false);
	let recordStatusFilter = $state('all');
	let isRetrying = $state(false);
	let isRetryingInsert = $state(false);
	let targetLanguages = $state([]);
	let correctionPopupData = $state(null);
	let showBulkReplace = $state(false);
	let loadedRunId = $state(null);
	let showBatches = $state(false);
	let batches = $state([]);
	let batchesLoading = $state(false);
	let recordsTotal = $state(0);
	let recordsPage = $state(1);
	let recordsLoadingMore = $state(false);
	let allRecordsLoaded = $state(false);

	function getRunStatusLabel(value) {
		const labels = {
			COMPLETED: getT()?.translate?.run?.completed || 'Completed',
			FAILED: getT()?.translate?.run?.translation_failed || 'Failed',
			RUNNING: getT()?.translate?.history?.status_running || 'Running',
			PENDING: getT()?.translate?.history?.status_pending || 'Pending',
			CANCELLED: getT()?.translate?.run?.cancelled || 'Cancelled',
		};
		return labels[value] || value;
	}

	let filteredRecords = $derived.by(() => {
		if (!records || records.length === 0) return [];
		if (recordStatusFilter === 'all') return records;
		return records.filter((r) => {
			if (recordStatusFilter === 'success') return r.status === 'SUCCESS';
			if (recordStatusFilter === 'failed') return r.status === 'FAILED';
			if (recordStatusFilter === 'skipped') return r.status === 'SKIPPED';
			return true;
		});
	});

	// Derived
	let insertStatusBadge = $derived.by(() => {
		const s = status?.insert_status;
		if (!s || s === 'success') return { label: getT()?.translate?.run?.success, class: 'bg-success-light text-success' };
		if (s === 'failed' || s === 'timeout') return { label: getT()?.translate?.run?.failed, class: 'bg-destructive-light text-destructive' };
		return { label: s, class: 'bg-warning-light text-warning' };
	});

	let insertMethodBadge = $derived.by(() => {
		const method = status?.insert_method;
		if (method === 'direct_db') {
			return {
				label: 'Direct DB',
				class: 'bg-primary-light text-primary',
				connectionName: status?.connection_snapshot?.name || '',
			};
		}
		return { label: 'SQL Lab', class: 'bg-surface-muted text-text-muted', connectionName: '' };
	});

	$effect(() => {
		if (!runId || loadedRunId === runId) return;
		loadedRunId = runId;
		loadData();
	});

	/** @returns {Promise<void>} */
	async function loadData() {
		try {
			const [statusData, recordsData] = await Promise.all([
				fetchRunStatus(runId),
				fetchRunRecords(runId, { page_size: 50, deduplicate: true }),
			]);
			status = statusData;
			records = recordsData?.items || [];
			recordsTotal = recordsData?.total || records.length;
			recordsPage = 1;
			allRecordsLoaded = records.length >= recordsTotal;

			// Extract target languages from language_stats or records
			if (statusData.language_stats && statusData.language_stats.length > 0) {
				targetLanguages = statusData.language_stats.map(l => l.language_code);
			} else {
				// Extract unique language codes from records
				const langSet = new SvelteSet();
				for (const rec of records) {
					if (rec.languages) {
						for (const lang of rec.languages) {
							langSet.add(lang.language_code);
						}
					}
				}
				targetLanguages = Array.from(langSet);
			}

			// Determine state
			const s = statusData.status;
			const insertS = statusData.insert_status;
			if (s === 'COMPLETED' && insertS === 'failed') {
				uxState = 'insert_failed';
			} else if (s === 'COMPLETED' && (statusData.failed_records || 0) > 0) {
				uxState = 'partial';
			} else if (s === 'FAILED') {
				uxState = 'failed';
			} else {
				uxState = 'completed';
			}
			// Auto-expand records when there are failures so user can inspect immediately
			if (uxState === 'failed' || uxState === 'partial') {
				showRecords = true;
			}
		} catch (err) {
			addToast(err?.message || getT()?.translate?.run?.load_failed, 'error');
		}
	}

	/** @returns {Promise<void>} */
	async function handleRetry() {
		isRetrying = true;
		try {
			await retryFailedBatches(runId);
			addToast(getT()?.translate?.run?.retry_success, 'success');
			await loadData();
			onRefresh();
		} catch (err) {
			addToast(err?.message || getT()?.translate?.run?.retry_failed_msg, 'error');
		} finally {
			isRetrying = false;
		}
	}

	/** @returns {Promise<void>} */
	async function handleRetryInsert() {
		isRetryingInsert = true;
		try {
			await retryInsert(runId);
			addToast(getT()?.translate?.run?.insert_retry_success, 'success');
			await loadData();
			onRefresh();
		} catch (err) {
			addToast(err?.message || getT()?.translate?.run?.insert_retry_failed_msg, 'error');
		} finally {
			isRetryingInsert = false;
		}
	}

	/** @param {string} text */
	function copyToClipboard(text) {
		navigator.clipboard.writeText(text).then(() => {
			addToast(getT()?.translate?.run?.copy_success, 'success');
		}).catch(() => {
			addToast(getT()?.translate?.run?.copy_failed, 'error');
		});
	}

	/** Load next page of unique rows and append to records list. */
	async function loadMoreRecords() {
		if (recordsLoadingMore) return;
		recordsLoadingMore = true;
		const nextPage = recordsPage + 1;
		try {
			const data = await fetchRunRecords(runId, { page: nextPage, page_size: 50, deduplicate: true });
			const newItems = data?.items || [];
			records = [...records, ...newItems];
			recordsPage = nextPage;
			allRecordsLoaded = records.length >= (data?.total || recordsTotal);
		} catch (e) {
			addToast(e?.message || 'Failed to load more records', 'error');
		} finally {
			recordsLoadingMore = false;
		}
	}
</script>

<div class="translation-run-result">
	{#if !status}
		<div class="bg-surface-muted border border-border rounded-lg p-4 text-center">
			<p class="text-sm text-text-muted">{_t.translate?.run?.loading_result}</p>
		</div>
	{:else}
		<div class="bg-surface-card border border-border rounded-lg p-4 space-y-4">
			<!-- Header -->
			<div class="flex items-center justify-between">
				<h3 class="text-lg font-semibold text-text">{_t.translate?.run?.result_title}</h3>
				<div class="flex items-center gap-2">
					<!-- Download CSV for failed/insert_failed runs with successful records -->
					{#if (uxState === 'insert_failed' || uxState === 'failed' || uxState === 'partial') && (status.successful_records || 0) > 0}
						<button
							onclick={async () => {
								try { await downloadFailedCsv(runId); }
								catch (e) { addToast(e?.message || 'Download failed', 'error'); }
							}}
							class="px-3 py-1.5 text-xs bg-primary-light text-primary rounded hover:bg-primary-light transition-colors"
						>
							{_t.translate?.run?.download_csv || 'CSV'}
						</button>
					{/if}
					<!-- Retry buttons -->
					{#if uxState === 'failed' || uxState === 'partial'}
						<button
							onclick={handleRetry}
							disabled={isRetrying}
							class="px-3 py-1.5 text-xs bg-primary text-white rounded hover:bg-primary-hover disabled:opacity-50 transition-colors"
						>
							{isRetrying ? _t.translate?.run?.retrying : _t.translate?.run?.retry_failed}
						</button>
					{/if}
					{#if uxState === 'insert_failed'}
						<button
							onclick={handleRetryInsert}
							disabled={isRetryingInsert}
							class="px-3 py-1.5 text-xs bg-warning-light text-white rounded hover:bg-warning-light disabled:opacity-50 transition-colors"
						>
							{isRetryingInsert ? _t.translate?.run?.retrying_insert : _t.translate?.run?.retry_insert}
						</button>
					{/if}
					<button
						onclick={() => showBulkReplace = true}
						class="px-3 py-1.5 text-xs bg-primary text-white rounded hover:bg-primary-hover transition-colors"
					>
						{_t.translate?.run?.bulk_replace || 'Bulk Replace'}
					</button>
				</div>
			</div>

			<!-- Statistics Grid -->
			<div class="grid grid-cols-2 sm:grid-cols-5 gap-4">
				<div class="bg-surface-muted rounded-lg p-3">
					<p class="text-xs text-text-muted uppercase">{_t.translate?.run?.total_records}</p>
					<p class="text-xl font-bold text-text">{status.total_records || 0}</p>
				</div>
				<div class="bg-success-light rounded-lg p-3">
					<p class="text-xs text-success uppercase">{_t.translate?.run?.success}</p>
					<p class="text-xl font-bold text-success">{status.successful_records || 0}</p>
				</div>
				<div class="bg-destructive-light rounded-lg p-3">
					<p class="text-xs text-destructive uppercase">{_t.translate?.run?.failed}</p>
					<p class="text-xl font-bold text-destructive">{status.failed_records || 0}</p>
				</div>
				<div class="bg-warning-light rounded-lg p-3">
					<p class="text-xs text-warning uppercase">{_t.translate?.run?.skipped}</p>
					<p class="text-xl font-bold text-warning">{status.skipped_records || 0}</p>
				</div>
				<div class="bg-info-light rounded-lg p-3">
					<p class="text-xs text-info uppercase">Cache</p>
					<p class="text-xl font-bold text-info">{status.cache_hits || 0}</p>
				</div>
			</div>

			<!-- Per-language Statistics -->
			{#if status.language_stats && status.language_stats.length > 0}
				<div class="border-t border-border pt-3">
					<p class="text-xs text-text-muted uppercase mb-2">{_t.translate?.run?.per_language ?? 'Per-Language Statistics'}</p>
					<div class="flex flex-wrap gap-3">
						{#each status.language_stats as lang}
							<div class="px-3 py-2 bg-surface-muted rounded border border-border min-w-[140px]">
								<p class="text-sm font-semibold text-text">{lang.language_code}</p>
								<div class="flex flex-wrap gap-x-3 gap-y-1 mt-1 text-xs">
									<span class="text-success" title="Translated">✓{lang.translated_rows}</span>
									{#if lang.failed_rows > 0}
										<span class="text-destructive" title="Failed">✗{lang.failed_rows}</span>
									{/if}
									{#if lang.skipped_rows > 0}
										<span class="text-warning" title="Skipped">⏭{lang.skipped_rows}</span>
									{/if}
									<span class="text-text-subtle" title="Total">∑{lang.total_rows}</span>
									{#if lang.token_count}
										<span class="text-info" title="Tokens">{_t.translate?.run?.tokens_label?.replace('{count}', lang.token_count.toLocaleString())}</span>
									{/if}
									{#if lang.estimated_cost}
										<span class="text-text-muted" title="Cost">{_t.translate?.run?.cost_label?.replace('{count}', lang.estimated_cost.toFixed(4))}</span>
									{/if}
								</div>
							</div>
						{/each}
					</div>
				</div>
			{/if}

			<!-- Status Details -->
			<div class="border-t border-border pt-3">
				<div class="grid grid-cols-2 gap-4 text-sm">
					<div>
						<span class="text-text-muted">{_t.translate?.run?.run_id}</span>
						<span class="ml-1 font-mono text-xs text-text">{status.id}</span>
						<button
							onclick={() => copyToClipboard(status.id)}
							class="ml-1 text-primary hover:text-primary text-xs"
							title={_t.translate?.run?.copy_id}
						>
							{_t.translate?.run?.copy_id}
						</button>
					</div>
					<div>
						<span class="text-text-muted">{_t.translate?.run?.status_label || 'Status'}</span>
						<span class="ml-1 text-xs font-medium text-text">{getRunStatusLabel(status.status)}</span>
					</div>
					<div>
						<span class="text-text-muted">{_t.translate?.run?.insert_status}</span>
						<span class="ml-1 inline-flex px-2 py-0.5 text-xs rounded-full font-medium {insertStatusBadge.class}">
							{insertStatusBadge.label}
						</span>
					</div>
					<div>
						<span class="text-text-muted">{_t.translate?.run?.insert_method || 'Insert Method'}</span>
						<span class="ml-1 inline-flex px-2 py-0.5 text-xs rounded-full font-medium {insertMethodBadge.class}">
							{insertMethodBadge.label}
						</span>
						{#if insertMethodBadge.connectionName}
							<span class="ml-1 text-xs text-text-muted">· {insertMethodBadge.connectionName}</span>
						{/if}
					</div>
					{#if status.superset_execution_id}
						<div>
							<span class="text-text-muted">{_t.translate?.run?.superset_query}</span>
							<span class="ml-1 font-mono text-xs text-text">{status.superset_execution_id}</span>
							<button
								onclick={() => copyToClipboard(status.superset_execution_id)}
								class="ml-1 text-primary hover:text-primary text-xs"
								title={_t.translate?.run?.copy_id}
							>
								{_t.translate?.run?.copy_id}
							</button>
						</div>
					{/if}
					{#if status.error_message}
						<div class="col-span-2">
							<span class="text-destructive text-xs">{_t.translate?.run?.error_label?.replace('{error}', status.error_message)}</span>
						</div>
					{/if}
				</div>
			</div>

			<!-- Batch Breakdown (collapsible) -->
			<div class="border-t border-border pt-3">
				<button
					onclick={async () => {
						showBatches = !showBatches;
						if (showBatches && batches.length === 0) {
							batchesLoading = true;
							try {
								const data = await fetchRunBatches(runId);
								batches = Array.isArray(data) ? data : [];
							} catch { /* ignore */ }
							batchesLoading = false;
						}
					}}
					class="flex items-center gap-2 text-sm text-text hover:text-text"
				>
					<svg
						class="w-4 h-4 transition-transform {showBatches ? 'rotate-90' : ''}"
						fill="none" stroke="currentColor" viewBox="0 0 24 24"
					>
						<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
					</svg>
					{_t.translate?.run?.batches_title?.replace('{count}', status.batch_count || batches.length || 0)}
				</button>

				{#if showBatches}
					<div class="mt-2 space-y-1">
						{#if batchesLoading}
							<div class="text-xs text-text-subtle">{_t.translate?.common?.loading}</div>
						{:else if batches.length === 0}
							<p class="text-xs text-text-subtle">{_t.translate?.common?.unknown}</p>
						{:else}
							{#each batches as batch, idx}
								<div class="flex items-center gap-3 bg-surface-muted rounded px-3 py-1.5 text-xs">
									<span class="font-medium text-text-muted w-8 shrink-0">
										{_t.translate?.run?.batch_number?.replace('{n}', batch.batch_index ?? idx + 1)}
									</span>
									<span class="inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium
										{batch.status === 'COMPLETED' ? 'bg-success-light text-success' : ''}
										{batch.status === 'FAILED' ? 'bg-destructive-light text-destructive' : ''}
										{batch.status === 'RUNNING' ? 'bg-primary-light text-primary' : ''}
										{!['COMPLETED','FAILED','RUNNING'].includes(batch.status) ? 'bg-surface-muted text-text-subtle' : ''}">
										{batch.status}
									</span>
									<span class="text-text-muted">
										{_t.translate?.run?.batch_records?.replace('{ok}', batch.successful_records || 0).replace('{total}', batch.total_records || 0)}
									</span>
									{#if batch.failed_records > 0}
										<span class="text-destructive">✗{batch.failed_records}</span>
									{/if}
									{#if batch.started_at && batch.completed_at}
										{@const bDur = ((new Date(batch.completed_at).getTime() - new Date(batch.started_at).getTime()) / 1000).toFixed(1)}
										<span class="text-text-subtle ml-auto">⏱ {_t.translate?.run?.batch_duration?.replace('{seconds}', bDur)}</span>
									{/if}
								</div>
							{/each}
						{/if}
					</div>
				{/if}
			</div>

			<!-- Event Invariants -->
			{#if status.event_invariants}
				<div class="border-t border-border pt-3">
					<div class="flex items-center gap-2 text-xs text-text-muted">
						<span>{_t.translate?.run?.event_invariants}</span>
						<span class="{status.event_invariants.invariant_valid ? 'text-success' : 'text-destructive'}">
							{status.event_invariants.invariant_valid ? _t.translate?.run?.valid : _t.translate?.run?.violated}
						</span>
						<span class="text-text-subtle">|</span>
						<span>{_t.translate?.run?.superset_query_id_label} {status.event_invariants.has_run_started ? _t.translate?.run?.started_yes : _t.translate?.run?.started_no}</span>
						<span class="text-text-subtle">|</span>
						<span>{_t.translate?.run?.terminal_events?.replace('{count}', status.event_invariants.terminal_event_count)}</span>
					</div>
				</div>
			{/if}

			<!-- Records Table with Per-Language Correction Cells -->
			{#if records.length > 0}
				<div class="border-t border-border pt-3">
					<div class="flex items-center justify-between mb-2">
						<button
							onclick={() => showRecords = !showRecords}
							class="flex items-center gap-2 text-sm text-text hover:text-text"
						>
							<svg
								class="w-4 h-4 transition-transform {showRecords ? 'rotate-90' : ''}"
								fill="none" stroke="currentColor" viewBox="0 0 24 24"
							>
								<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
							</svg>
							{_t.translate?.run?.records_title || 'Translation Records'} ({records.length}{#if recordsTotal > records.length}/{recordsTotal}{/if})
						</button>
						<div class="flex items-center gap-2">
							{#if !allRecordsLoaded && recordsTotal > records.length}
								<button
									onclick={loadMoreRecords}
									disabled={recordsLoadingMore}
									class="px-2.5 py-1 text-xs border border-border-strong text-text-muted rounded hover:bg-surface-muted disabled:opacity-50 transition-colors"
								>
									{recordsLoadingMore
										? _t.translate?.common?.loading
										: (_t.translate?.run?.load_more_records || 'Load more') + ' (' + (recordsTotal - records.length) + ')'}
								</button>
							{/if}
						</div>
					</div>

					{#if showRecords}
						<div class="flex flex-wrap gap-2 mb-3">
							{#each ['all','success','failed','skipped'] as filter}
								<button
									onclick={() => recordStatusFilter = filter}
									class="px-2.5 py-1 text-xs rounded-full border transition-colors
										{recordStatusFilter === filter
											? 'bg-primary-light border-primary-ring text-primary'
											: 'bg-surface-card border-border text-text-muted hover:border-border-strong'}"
								>
									{_t.translate?.run?.['records_filter_' + filter] || filter}
									{#if filter !== 'all'}
										<span class="ml-1 text-text-subtle">
											({records.filter((r) => (filter === 'success' ? r.status === 'SUCCESS' : filter === 'failed' ? r.status === 'FAILED' : r.status === 'SKIPPED')).length})
										</span>
									{/if}
								</button>
							{/each}
						</div>

						<div class="overflow-x-auto border border-border rounded-lg">
							<table class="w-full text-sm">
								<thead class="bg-surface-muted">
									<tr>
										<th class="px-3 py-2 text-left text-xs font-medium text-text-muted uppercase w-12">#</th>
										<th class="px-3 py-2 text-left text-xs font-medium text-text-muted uppercase min-w-[150px]">{_t.translate?.preview?.table_source || 'Source'}</th>
										{#each targetLanguages as lang}
											<th class="px-3 py-2 text-left text-xs font-medium text-text-muted uppercase min-w-[180px]">
												<div class="flex items-center gap-1">
													<span class="font-mono text-primary">{lang}</span>
												</div>
											</th>
										{/each}
										{#if targetLanguages.length === 0}
											<th class="px-3 py-2 text-left text-xs font-medium text-text-muted uppercase min-w-[180px]">{_t.translate?.preview?.translation || 'Translation'}</th>
										{/if}
										<th class="px-3 py-2 text-center text-xs font-medium text-text-muted uppercase w-20">{_t.translate?.preview?.table_status || 'Status'}</th>
										<th class="px-3 py-2 text-center text-xs font-medium text-text-muted uppercase w-24">{_t.translate?.preview?.table_actions || 'Actions'}</th>
									</tr>
								</thead>
								<tbody class="divide-y divide-border">
									{#each filteredRecords as row, idx}
										<tr class="{row.status === 'FAILED' ? 'bg-destructive-light' : idx % 2 === 0 ? 'bg-surface-card' : 'bg-surface-muted/50'}">
											<td class="px-3 py-2 text-xs text-text-subtle align-top">{idx + 1}</td>
											<td class="px-3 py-2 align-top max-w-[240px]">
												<div class="text-xs text-text break-all line-clamp-3">{row.source_sql || row.source_object_name || '—'}</div>
												{#if row.source_data && typeof row.source_data === 'object'}
													<div class="text-[10px] text-text-subtle mt-0.5 font-mono truncate" title={JSON.stringify(row.source_data)}>
														{Object.values(row.source_data).filter(Boolean).join(' · ')}
													</div>
												{/if}
											</td>
											{#if targetLanguages.length > 0}
												{#each targetLanguages as lang}
													{@const langData = (row.languages || []).find(l => l.language_code === lang)}
													{@const cellValue = langData?.final_value || langData?.translated_value || ''}
													{@const detectedSource = langData?.source_language_detected || row.source_language_detected || ''}
													<td class="px-3 py-2 align-top">
														<CorrectionCell
															value={cellValue}
															recordId={row.id}
															languageCode={lang}
															runId={runId}
															sourceLanguage={detectedSource}
														/>
													</td>
												{/each}
											{:else}
												<td class="px-3 py-2 align-top">
													<CorrectionCell
														value={row.final_value || row.llm_translation || row.target_sql || ''}
														recordId={row.id}
														languageCode=""
														runId={runId}
														sourceLanguage=""
													/>
												</td>
											{/if}
											<td class="px-3 py-2 text-center align-top">
												<span class="inline-flex px-2 py-0.5 text-xs rounded-full font-medium
													{row.status === 'SUCCESS' ? 'bg-success-light text-success' : ''}
													{row.status === 'FAILED' ? 'bg-destructive-light text-destructive' : ''}
													{row.status === 'SKIPPED' ? 'bg-warning-light text-warning' : ''}
													{!['SUCCESS','FAILED','SKIPPED'].includes(row.status) ? 'bg-surface-muted text-text-muted' : ''}
												">
													{row.status}
												</span>
											</td>
											<td class="px-3 py-2 text-center align-top">
												<button
													onclick={() => {
														const firstLang = row.languages?.[0] || {};
														correctionPopupData = {
															sourceTerm: row.source_sql || row.source_object_name || '',
															incorrectTarget: firstLang?.final_value || firstLang?.translated_value || '',
															sourceLanguage: firstLang?.source_language_detected || row.source_language_detected || '',
															targetLanguage: targetLanguages[0] || '',
															runId,
															rowKey: row.id
														};
													}}
													class="px-2 py-0.5 text-[10px] bg-primary text-white rounded hover:bg-primary-hover transition-colors"
													title="Submit Correction"
												>
													{_t.translate?.run?.correct || 'Correct'}
												</button>
											</td>
										</tr>
									{/each}
								</tbody>
							</table>
						</div>
						{#if recordsTotal > 0}
							<p class="text-xs text-text-subtle mt-1">
								{(_t.translate?.run?.showing_records || 'Showing {count} of {total} unique rows.')
									.replace('{count}', filteredRecords.length)
									.replace('{total}', recordsTotal)}
							</p>
						{/if}
					{/if}
				</div>
			{/if}
		</div>
	{/if}
</div>

<!-- Integration: Orphaned Components -->
<TermCorrectionPopup
	{...(correctionPopupData || {})}
	onClose={() => correctionPopupData = null}
	onSubmitted={() => { correctionPopupData = null; loadData(); onRefresh(); }}
/>

<BulkReplaceModal
	show={showBulkReplace}
	{runId}
	{targetLanguages}
	onClose={() => showBulkReplace = false}
	onApplied={(_count) => { showBulkReplace = false; loadData(); onRefresh(); }}
/>
<!-- #endregion TranslationRunResult -->
