<!-- #region TranslationPreview [C:2] [TYPE Component] [SEMANTICS translate, preview, multi-language, cost] -->
<!-- @ingroup Translate -->
<!-- @BRIEF Informational preview — sample rows from datasource passed through LLM to verify translation works and language detection is correct. No quality gate, no approve/reject/edit. -->
<!-- @RELATION DEPENDS_ON -> [TranslateApi] -->
<!-- @UX_STATE idle -> Initial state, no preview loaded -->
<!-- @UX_STATE loading -> Preview API call in progress -->
<!-- @UX_STATE preview_loaded -> Preview data displayed with dynamic language columns -->
<!-- @UX_STATE preview_error -> Preview API call failed -->
<!-- @UX_FEEDBACK spinner during preview; cost warning for large previews. -->
<!-- @UX_RECOVERY retry preview; re-fetch with updated config. -->
<script lang="ts">
	import { getT } from '$lib/i18n/index.svelte.js';
	import { addToast } from '$lib/toasts.svelte.js';
	import { fetchPreview } from '$lib/api/translate.js';

	/** @type {{ jobId: string, environmentId?: string }} */
	let { jobId, environmentId = '' } = $props();

	/** @type {'idle'|'loading'|'preview_loaded'|'preview_error'} */
	let uxState = $state('idle');
  // @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 records = $state([]);
	let targetLanguages = $state([]);
	let costEstimate = $state(null);
	let errorMessage = $state('');
	let sampleSize = $state(10);

	/** Get translated value for a record and language code */
	function getLangValue(record, langCode) {
		const lang = (record.languages || []).find(l => l.language_code === langCode);
		return lang ? (lang.final_value || lang.translated_value || '') : '';
	}

	/** Get detected language for a record */
	function getDetectedLang(record) {
		if (record.source_language_detected && record.source_language_detected !== 'und') {
			return record.source_language_detected;
		}
		const langs = record.languages || [];
		for (const l of langs) {
			if (l.source_language_detected && l.source_language_detected !== 'und') {
				return l.source_language_detected;
			}
		}
		return 'und';
	}

	/** @returns {Promise<void>} */
	async function handlePreview() {
		uxState = 'loading';
		errorMessage = '';
		try {
			const result = await fetchPreview(jobId, sampleSize, environmentId);
			records = (result.records || []).map(r => ({ ...r }));
			targetLanguages = result.target_languages || [];
			costEstimate = result.cost_estimate || null;
			uxState = 'preview_loaded';
			addToast(getT()?.translate?.preview?.preview_loaded?.replace('{count}', records.length), 'success');
		} catch (err) {
			errorMessage = err?.message || getT()?.translate?.preview?.preview_failed;
			uxState = 'preview_error';
			addToast(errorMessage, 'error');
		}
	}
</script>

<div class="translation-preview">
	<!-- Header -->
	<div class="flex items-center justify-between mb-4">
		<h3 class="text-lg font-semibold text-text">{_t.translate?.preview?.title}</h3>
	</div>

	<!-- Idle State -->
	{#if uxState === 'idle'}
		<div class="bg-surface-muted border border-border rounded-lg p-6 text-center">
			<p class="text-sm text-text-muted mb-4">
				{_t.translate?.preview?.title} &mdash; {_t.translate?.preview?.sample_size} {sampleSize}
			</p>
			<div class="flex items-center justify-center gap-3 mb-4">
				<label for="preview-sample-size" class="text-sm text-text-muted">{_t.translate?.preview?.sample_size}</label>
				<input
					type="range"
					bind:value={sampleSize}
					min="1"
					max="100"
					id="preview-sample-size"
					class="w-40 accent-blue-600"
				/>
				<span class="text-sm font-mono text-text w-8 text-left">{sampleSize}</span>
			</div>
			{#if sampleSize > 30}
				<div class="flex items-center justify-center gap-2 mb-4 text-warning bg-warning-light border border-warning rounded-lg px-4 py-2 mx-auto max-w-md">
					<svg class="w-4 h-4 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
						<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
					</svg>
					<span class="text-xs font-medium">{(_t.translate?.preview?.cost_warning) || 'Large sample size may incur higher costs'}</span>
				</div>
			{/if}
			<button
				onclick={handlePreview}
				class="px-6 py-2 bg-primary text-white rounded-lg hover:bg-primary-hover transition-colors text-sm"
			>
				{_t.translate?.preview?.run_preview}
			</button>
		</div>

	<!-- Loading State -->
	{:else if uxState === 'loading'}
		<div class="bg-surface-card border border-border rounded-lg p-6">
			<div class="flex items-center gap-3 mb-4">
				<div class="animate-spin rounded-full h-5 w-5 border-b-2 border-primary-ring"></div>
				<span class="text-sm text-text-muted">{_t.translate?.preview?.running_preview}</span>
			</div>
			<div class="space-y-3">
				{#each Array(3) as _}
					<div class="h-12 bg-surface-muted rounded animate-pulse"></div>
				{/each}
			</div>
		</div>

	<!-- Error State -->
	{:else if uxState === 'preview_error'}
		<div class="bg-destructive-light border border-destructive-ring rounded-lg p-4">
			<p class="text-sm text-destructive mb-3">{errorMessage}</p>
			<div class="flex items-center gap-3">
				<button
					onclick={handlePreview}
					class="px-4 py-1.5 bg-destructive text-white rounded-lg hover:bg-destructive-hover transition-colors text-sm"
				>
					{_t.translate?.preview?.retry_preview}
				</button>
				<label class="text-sm text-text-muted flex items-center gap-2">
					{_t.translate?.preview?.sample_size}
					<input
						type="range"
						bind:value={sampleSize}
						min="1"
						max="100"
						class="w-24 accent-blue-600"
					/>
					<span class="text-xs font-mono text-text-muted w-6">{sampleSize}</span>
				</label>
			</div>
		</div>

	<!-- Preview Loaded State -->
	{:else if uxState === 'preview_loaded'}
		<!-- Cost Estimate Card -->
		{#if costEstimate}
			<div class="bg-gradient-to-r from-blue-50 to-indigo-50 border border-primary-ring rounded-lg p-4 mb-4">
				<h4 class="text-sm font-medium text-primary mb-2">{_t.translate?.preview?.cost_estimate}</h4>
				<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 text-sm">
					<div>
						<span class="text-primary">{_t.translate?.preview?.sample_rows}</span>
						<span class="ml-1 font-semibold">{costEstimate.sample_size}</span>
					</div>
					<div>
						<span class="text-primary">{_t.translate?.preview?.sample_tokens}</span>
						<span class="ml-1 font-semibold">{costEstimate.sample_total_tokens?.toLocaleString()}</span>
					</div>
					<div>
						<span class="text-primary">{_t.translate?.preview?.sample_cost}</span>
						<span class="ml-1 font-semibold">${costEstimate.sample_cost?.toFixed(6)}</span>
					</div>
					<div>
						<span class="text-primary">{_t.translate?.preview?.est_total_cost}</span>
						<span class="ml-1 font-semibold">${costEstimate.estimated_cost?.toFixed(6)}</span>
					</div>
				</div>
				<p class="text-xs text-primary mt-1">
					{_t.translate?.preview?.across_languages?.replace('{count}', costEstimate.num_languages || targetLanguages.length || 1)}
				</p>
				{#if costEstimate.warning}
					<div class="mt-2 flex items-center gap-2 text-warning bg-warning-light border border-warning rounded px-3 py-2">
						<svg class="w-4 h-4 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
							<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
						</svg>
						<span class="text-xs font-medium">{costEstimate.warning}</span>
					</div>
				{/if}
			</div>
		{/if}

		<!-- Stats Bar (simplified — no approve/reject/pending) -->
		<div class="flex items-center justify-between mb-3 text-sm">
			<div class="flex gap-4">
				<span class="text-text-muted">{_t.translate?.preview?.rows_count?.replace('{count}', records.length)}</span>
				{#if targetLanguages.length > 0}
					<span class="text-primary">{_t.translate?.preview?.languages_count?.replace('{count}', targetLanguages.length)}</span>
				{/if}
			</div>
			<button
				onclick={handlePreview}
				class="px-3 py-1 text-xs border border-border-strong text-text-muted rounded hover:bg-surface-muted transition-colors"
			>
				{_t.translate?.preview?.re_run}
			</button>
		</div>

		<!-- Dynamic Multi-Language Table (read-only) -->
		<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">{_t.translate?.preview?.table_source}</th>
						<th class="px-3 py-2 text-center text-xs font-medium text-text-muted uppercase w-28">{_t.translate?.preview?.detected_language}</th>
						{#each targetLanguages as lang}
							<th class="px-3 py-2 text-left text-xs font-medium text-text-muted uppercase min-w-[250px]">
								<div class="flex items-center gap-1">
									<span class="font-mono text-primary">{lang}</span>
								</div>
							</th>
						{/each}
					</tr>
				</thead>
				<tbody class="divide-y divide-border">
					{#each records as row, idx}
						<tr class="{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 min-w-[200px]">
								<div class="max-h-32 overflow-y-auto">
									<code class="text-xs text-text whitespace-pre-wrap break-all">{row.source_sql || _t.translate?.preview?.empty_placeholder}</code>
								</div>
							</td>
							<td class="px-3 py-2 text-center align-top">
							<span class="inline-flex items-center gap-1 px-2 py-0.5 text-xs rounded-full font-mono
								{getDetectedLang(row) !== 'und' ? 'bg-info-light text-info' : 'bg-warning-light text-warning'}">
								{getDetectedLang(row)}
								{#if getDetectedLang(row) === 'und'}
									<span class="text-[10px] font-bold" title="Undetermined source language">⚠</span>
								{/if}
							</span>
							</td>
							{#each targetLanguages as lang}
								{@const langVal = getLangValue(row, lang)}
								<td class="px-3 py-2 align-top">
									<div class="max-h-32 overflow-y-auto">
										<code class="text-xs whitespace-pre-wrap break-all text-text">
											{langVal || _t.translate?.preview?.pending_placeholder}
										</code>
									</div>
								</td>
							{/each}
						</tr>
					{/each}
				</tbody>
			</table>
		</div>
	{/if}
</div>
<!-- #endregion TranslationPreview -->
