<!-- #region TranslateHistoryPage [C:3] [TYPE Page] [SEMANTICS sveltekit, translate, history, run, metrics] -->
<script lang="ts">
	import { onMount } from 'svelte';
	import { addToast } from '$lib/toasts.svelte.js';
	import { t, _ } from '$lib/i18n/index.svelte.js';
	import {
		fetchAllRuns,
		fetchRunDetail,
		fetchAllMetrics,
		fetchJobs,
		downloadSkippedCsv,
		downloadFailedCsv,
		cancelRun,
		retryFailedBatches
	} from '$lib/api/translate.js';

	/** @type {'idle'|'loading'|'empty'|'populated'|'detail_open'|'pruned'} */
	let uxState = $state('idle');

	let cancellingRunId = $state(null);
	let retryingRunId = $state(null);

	let runs = $state([]);
	let total = $state(0);
	let currentPage = $state(1);
	let pageSize = $state(20);
	let selectedRun = $state(null);
	let selectedRunDetail = $state(null);
	let isLoading = $state(false);
	let metrics = $state([]);
	let jobs = $state([]);

	// Filters
	let filterJobId = $state('');
	let filterStatus = $state('');
	let filterTrigger = $state('');
	let filterDateFrom = $state('');
	let filterDateTo = $state('');

	onMount(() => {
		loadRuns();
		loadMetrics();
		loadJobs();
	});

	async function loadRuns() {
		isLoading = true;
		uxState = 'loading';
		try {
			const result = await fetchAllRuns({
				page: currentPage,
				page_size: pageSize,
				job_id: filterJobId || undefined,
				status: filterStatus || undefined,
				trigger_type: filterTrigger || undefined,
			});
			runs = result?.items || [];
			total = result?.total || 0;
			uxState = runs.length === 0 ? 'empty' : 'populated';
		} catch (err) {
			addToast(err?.message || _('translate.history.load_failed'), 'error');
			uxState = 'empty';
		} finally {
			isLoading = false;
		}
	}

	async function loadMetrics() {
		try {
			metrics = await fetchAllMetrics();
		} catch (err) {
			// Non-critical
		}
	}

	async function loadJobs() {
		try {
			const result = await fetchJobs({ page_size: 100 });
			jobs = Array.isArray(result) ? result : (result?.items || result?.results || []);
		} catch (err) {
			// Non-critical
		}
	}

	async function openDetail(run) {
		selectedRun = run;
		selectedRunDetail = null;
		try {
			selectedRunDetail = await fetchRunDetail(run.id);
			uxState = 'detail_open';
		} catch (err) {
			addToast(err?.message || _('translate.history.load_detail_failed'), 'error');
		}
	}

	function closeDetail() {
		selectedRun = null;
		selectedRunDetail = null;
		uxState = runs.length === 0 ? 'empty' : 'populated';
	}

	function applyFilters() {
		currentPage = 1;
		loadRuns();
	}

	function getStatusClass(status) {
		const map = {
			PENDING: 'bg-yellow-100 text-yellow-700',
			RUNNING: 'bg-blue-100 text-blue-700',
			COMPLETED: 'bg-green-100 text-green-700',
			FAILED: 'bg-red-100 text-red-700',
			CANCELLED: 'bg-gray-100 text-gray-500',
		};
		return map[status] || 'bg-gray-100 text-gray-700';
	}

	function getJobName(jobId) {
		const job = jobs.find(j => j.id === jobId);
		return job ? job.name : jobId?.substring(0, 8) + '...';
	}

	async function handleCancelRun(runId) {
		cancellingRunId = runId;
		try {
			await cancelRun(runId);
			addToast($t.translate?.run?.run_cancelled || 'Run cancelled', 'success');
			// Refresh the detail panel and list
			if (selectedRunDetail?.id === runId) {
				selectedRunDetail = await fetchRunDetail(runId);
			}
			loadRuns();
		} catch (err) {
			addToast(err?.message || $t.translate?.run?.cancel_failed || 'Failed to cancel run', 'error');
		} finally {
			cancellingRunId = null;
		}
	}

	async function handleRetryRun(runId) {
		retryingRunId = runId;
		try {
			await retryFailedBatches(runId);
			addToast($t.translate?.run?.retry_success || 'Retry started', 'success');
			// Refresh the detail panel and list
			if (selectedRunDetail?.id === runId) {
				selectedRunDetail = await fetchRunDetail(runId);
			}
			loadRuns();
		} catch (err) {
			addToast(err?.message || $t.translate?.run?.retry_failed_msg || 'Retry failed', 'error');
		} finally {
			retryingRunId = null;
		}
	}

	async function handleDownloadSkipped(runId) {
		try {
			await downloadSkippedCsv(runId);
		} catch (err) {
			addToast(err?.message || _('translate.history.download_failed'), 'error');
		}
	}

	async function handleDownloadFailed(runId) {
		try {
			await downloadFailedCsv(runId);
		} catch (err) {
			addToast(err?.message || _('translate.history.download_failed'), 'error');
		}
	}

	function totalMetric() {
		if (!metrics.length) return null;
		const agg = {
			total_runs: metrics.reduce((s, m) => s + (m.total_runs || 0), 0),
			successful_runs: metrics.reduce((s, m) => s + (m.successful_runs || 0), 0),
			failed_runs: metrics.reduce((s, m) => s + (m.failed_runs || 0), 0),
			total_records: metrics.reduce((s, m) => s + (m.total_records || 0), 0),
		};
		return agg;
	}
</script>

<div class="container mx-auto px-4 py-6">
	<div class="flex items-center justify-between mb-6">
		<div>
			<h1 class="text-2xl font-bold text-gray-900">{$t.translate?.history?.title}</h1>
			<p class="text-sm text-gray-500 mt-1">{$t.translate?.history?.subtitle}</p>
		</div>
		<button onclick={() => { currentPage = 1; applyFilters(); }} class="px-4 py-2 text-sm text-white bg-primary rounded-lg hover:bg-primary-hover">
			{$t.translate?.history?.refresh}
		</button>
	</div>

	<!-- Metrics Summary -->
	{#if totalMetric()}
		<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-6">
			<div class="bg-gray-50 rounded-lg p-3">
				<p class="text-xs text-gray-500 uppercase">{$t.translate?.history?.total_runs}</p>
				<p class="text-xl font-bold text-gray-900">{totalMetric().total_runs}</p>
			</div>
			<div class="bg-green-50 rounded-lg p-3">
				<p class="text-xs text-green-600 uppercase">{$t.translate?.history?.successful}</p>
				<p class="text-xl font-bold text-green-700">{totalMetric().successful_runs}</p>
			</div>
			<div class="bg-destructive-light rounded-lg p-3">
				<p class="text-xs text-red-600 uppercase">{$t.translate?.history?.failed}</p>
				<p class="text-xl font-bold text-red-700">{totalMetric().failed_runs}</p>
			</div>
			<div class="bg-primary-light rounded-lg p-3">
				<p class="text-xs text-blue-600 uppercase">{$t.translate?.history?.records}</p>
				<p class="text-xl font-bold text-blue-700">{totalMetric().total_records}</p>
			</div>
		</div>
	{/if}

	<!-- Filters -->
	<div class="bg-white border border-gray-200 rounded-lg p-4 mb-4">
		<div class="grid grid-cols-2 sm:grid-cols-5 gap-3">
			<select bind:value={filterJobId} class="px-3 py-2 border border-gray-300 rounded-lg text-sm">
				<option value="">{$t.translate?.history?.all_jobs}</option>
				{#each jobs as job}
					<option value={job.id}>{job.name}</option>
				{/each}
			</select>
			<select bind:value={filterStatus} class="px-3 py-2 border border-gray-300 rounded-lg text-sm">
				<option value="">{$t.translate?.history?.all_status}</option>
				<option value="PENDING">{$t.translate?.history?.status_pending}</option>
				<option value="RUNNING">{$t.translate?.history?.status_running}</option>
				<option value="COMPLETED">{$t.translate?.history?.status_completed}</option>
				<option value="FAILED">{$t.translate?.history?.status_failed}</option>
				<option value="CANCELLED">{$t.translate?.history?.status_cancelled}</option>
			</select>
			<select bind:value={filterTrigger} class="px-3 py-2 border border-gray-300 rounded-lg text-sm">
				<option value="">{$t.translate?.history?.all_triggers}</option>
				<option value="manual">{$t.translate?.history?.trigger_manual}</option>
				<option value="scheduled">{$t.translate?.history?.trigger_scheduled}</option>
				<option value="baseline_expired">{$t.translate?.history?.trigger_baseline_expired}</option>
			</select>
			<input type="date" bind:value={filterDateFrom} class="px-3 py-2 border border-gray-300 rounded-lg text-sm" placeholder={$t.translate?.common?.from} />
			<button onclick={applyFilters} class="px-4 py-2 text-sm bg-primary text-white rounded-lg hover:bg-primary-hover">
				{$t.translate?.history?.filter}
			</button>
		</div>
	</div>

	<!-- Loading state -->
	{#if isLoading}
		<div class="space-y-3">
			{#each Array(5) as _}
				<div class="h-16 bg-gray-100 rounded-lg animate-pulse" />
			{/each}
		</div>

	<!-- Empty state -->
	{:else if uxState === 'empty'}
		<div class="bg-gray-50 border border-dashed border-gray-300 rounded-lg p-12 text-center">
			<svg class="w-16 h-16 text-gray-300 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
				<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
			</svg>
			<p class="text-gray-500 mb-2">{$t.translate?.history?.no_runs}</p>
			<p class="text-xs text-gray-400">{$t.translate?.history?.no_runs_hint}</p>
		</div>

	<!-- Populated state -->
	{:else if uxState === 'populated' || uxState === 'detail_open'}
		<div class="space-y-2">
			{#each runs as run}
				<div
					onclick={() => openDetail(run)}
					class="bg-white border border-gray-200 rounded-lg p-3 hover:shadow-sm hover:border-gray-300 transition-all cursor-pointer"
				>
					<div class="flex items-center justify-between">
						<div class="flex-1 min-w-0">
							<div class="flex items-center gap-2 mb-1">
								<span class="text-sm font-medium text-gray-900">{getJobName(run.job_id)}</span>
								<span class="inline-flex px-2 py-0.5 text-xs rounded-full {getStatusClass(run.status)}">
									{run.status}
								</span>
								{#if run.trigger_type}
									<span class="text-xs text-gray-400 bg-gray-100 px-2 py-0.5 rounded">{run.trigger_type}</span>
								{/if}
							</div>
							<div class="flex items-center gap-3 text-xs text-gray-400">
								<span>{run.created_at ? new Date(run.created_at).toLocaleString() : ''}</span>
								<span>{_('translate.history.records_label').replace('{count}', run.total_records || 0)}</span>
								<span>{_('translate.history.ok_label').replace('{count}', run.successful_records || 0)}</span>
								<span>{_('translate.history.fail_label').replace('{count}', run.failed_records || 0)}</span>
								{#if run.created_by}
									<span>{_('translate.history.by_label').replace('{user}', run.created_by)}</span>
								{/if}
							</div>
							<!-- Languages badges -->
							{#if run.target_languages && run.target_languages.length > 0}
								<div class="flex gap-1 mt-1">
									{#each run.target_languages as lang}
										<span class="px-1.5 py-0.5 text-xs rounded bg-blue-100 text-blue-700">{lang}</span>
									{/each}
								</div>
							{/if}
						</div>
						<div class="flex items-center gap-2 ml-2" onclick={(e) => e.stopPropagation()}>
							{#if run.status === 'PENDING' || run.status === 'RUNNING'}
								<button
									onclick={() => handleCancelRun(run.id)}
									disabled={cancellingRunId === run.id}
									class="px-2 py-1 text-xs bg-red-100 text-red-700 rounded hover:bg-red-200 disabled:opacity-50 transition-colors"
								>
									{cancellingRunId === run.id
										? ($t.translate?.run?.cancelling || '...')
										: ($t.translate?.run?.cancel || 'Cancel')}
								</button>
							{/if}
							{#if run.status === 'FAILED'}
								<button
									onclick={() => handleRetryRun(run.id)}
									disabled={retryingRunId === run.id}
									class="px-2 py-1 text-xs bg-amber-100 text-amber-700 rounded hover:bg-amber-200 disabled:opacity-50 transition-colors"
								>
									{retryingRunId === run.id
										? ($t.translate?.run?.retrying || '...')
										: ($t.translate?.run?.retry_failed || 'Retry')}
								</button>
							{/if}
							{#if run.status === 'COMPLETED' && (run.skipped_records || 0) > 0}
								<button
									onclick={() => handleDownloadSkipped(run.id)}
									class="text-xs text-primary hover:text-primary-hover"
								>
									{$t.translate?.history?.skipped_csv}
								</button>
							{/if}
							{#if run.status === 'FAILED' && (run.successful_records || 0) > 0}
								<button
									onclick={() => handleDownloadFailed(run.id)}
									class="text-xs text-primary hover:text-primary-hover"
								>
									{$t.translate?.history?.failed_csv || 'Download CSV'}
								</button>
							{/if}
							<svg class="w-4 h-4 text-gray-400" 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>
						</div>
					</div>
				</div>
			{/each}
		</div>

		<!-- Pagination -->
		<div class="flex items-center justify-between mt-4">
			<p class="text-sm text-gray-500">{_('translate.history.showing').replace('{count}', runs.length).replace('{total}', total)}</p>
			<div class="flex gap-2">
				<button
					onclick={() => { currentPage--; loadRuns(); }}
					disabled={currentPage <= 1}
					class="px-3 py-1.5 text-sm border border-gray-200 rounded-lg disabled:opacity-50"
				>
					{$t.translate?.history?.previous}
				</button>
				<button
					onclick={() => { currentPage++; loadRuns(); }}
					disabled={currentPage * pageSize >= total}
					class="px-3 py-1.5 text-sm border border-gray-200 rounded-lg disabled:opacity-50"
				>
					{$t.translate?.history?.next}
				</button>
			</div>
		</div>
	{/if}

	<!-- Detail panel (slide-over) -->
	{#if uxState === 'detail_open' && selectedRunDetail}
		<div class="fixed inset-0 z-50 bg-black/30" onclick={closeDetail}></div>
		<div class="fixed right-0 top-0 h-full w-full max-w-2xl bg-white shadow-xl z-50 overflow-y-auto">
			<div class="p-6">
				<div class="flex items-center justify-between mb-6">
					<h2 class="text-xl font-bold text-gray-900">{$t.translate?.history?.run_detail}</h2>
					<button onclick={closeDetail} class="text-gray-400 hover:text-gray-600">
						<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
							<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
						</svg>
					</button>
				</div>

				<!-- Status row -->
				<div class="grid grid-cols-2 gap-4 mb-6">
					<div>
						<p class="text-xs text-gray-500 uppercase">{$t.translate?.history?.status}</p>
						<span class="inline-flex px-2 py-1 text-sm rounded-full {getStatusClass(selectedRunDetail.status)}">
							{selectedRunDetail.status}
						</span>
					</div>
					<div>
						<p class="text-xs text-gray-500 uppercase">{$t.translate?.history?.trigger}</p>
						<p class="text-sm font-medium text-gray-900">{selectedRunDetail.trigger_type || 'manual'}</p>
					</div>
					<div>
						<p class="text-xs text-gray-500 uppercase">{$t.translate?.history?.started}</p>
						<p class="text-sm text-gray-900">{selectedRunDetail.started_at ? new Date(selectedRunDetail.started_at).toLocaleString() : '-'}</p>
					</div>
					<div>
						<p class="text-xs text-gray-500 uppercase">{$t.translate?.history?.completed}</p>
						<p class="text-sm text-gray-900">{selectedRunDetail.completed_at ? new Date(selectedRunDetail.completed_at).toLocaleString() : '-'}</p>
					</div>
				</div>

				<!-- Stats Grid -->
				<div class="grid grid-cols-4 gap-3 mb-6">
					<div class="bg-gray-50 rounded p-3 text-center">
						<p class="text-lg font-bold text-gray-900">{selectedRunDetail.total_records || 0}</p>
						<p class="text-xs text-gray-500">{$t.translate?.history?.total}</p>
					</div>
					<div class="bg-green-50 rounded p-3 text-center">
						<p class="text-lg font-bold text-green-700">{selectedRunDetail.successful_records || 0}</p>
						<p class="text-xs text-green-600">{$t.translate?.history?.success}</p>
					</div>
					<div class="bg-destructive-light rounded p-3 text-center">
						<p class="text-lg font-bold text-red-700">{selectedRunDetail.failed_records || 0}</p>
						<p class="text-xs text-red-600">{$t.translate?.history?.failed}</p>
					</div>
					<div class="bg-yellow-50 rounded p-3 text-center">
						<p class="text-lg font-bold text-yellow-700">{selectedRunDetail.skipped_records || 0}</p>
						<p class="text-xs text-yellow-600">{$t.translate?.history?.skipped}</p>
					</div>
				</div>

				<!-- Per-Language Statistics -->
				{#if selectedRunDetail.language_stats && Object.keys(selectedRunDetail.language_stats).length > 0}
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-700 mb-2">{$t.translate?.run?.per_language}</h3>
						<div class="space-y-2">
							{#each Object.entries(selectedRunDetail.language_stats) as [lang, stats]}
								<div class="bg-gray-50 rounded-lg p-3">
									<div class="flex items-center justify-between mb-1">
										<span class="text-sm font-medium text-gray-900">{lang}</span>
									</div>
									<div class="grid grid-cols-4 gap-2 text-xs text-gray-600">
										<span>{_('translate.run.translated_label').replace('{count}', stats.translated_rows)}</span>
										<span>{_('translate.run.failed_label').replace('{count}', stats.failed_rows)}</span>
										<span>{_('translate.run.skipped_label').replace('{count}', stats.skipped_rows)}</span>
										<span>{_('translate.run.tokens_label').replace('{count}', stats.token_count)}</span>
									</div>
								</div>
							{/each}
						</div>
					</div>
				{/if}

				<!-- Action Buttons -->
				<div class="flex items-center gap-3 mb-6">
					{#if selectedRunDetail.status === 'PENDING' || selectedRunDetail.status === 'RUNNING'}
						<button
							onclick={() => handleCancelRun(selectedRunDetail.id)}
							disabled={cancellingRunId === selectedRunDetail.id}
							class="px-4 py-2 text-sm bg-destructive text-white rounded-lg hover:bg-destructive-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
						>
							{cancellingRunId === selectedRunDetail.id
								? ($t.translate?.run?.cancelling || 'Cancelling...')
								: ($t.translate?.run?.cancel || 'Cancel')}
						</button>
					{/if}
					{#if selectedRunDetail.status === 'FAILED'}
						<button
							onclick={() => handleRetryRun(selectedRunDetail.id)}
							disabled={retryingRunId === selectedRunDetail.id}
							class="px-4 py-2 text-sm bg-amber-600 text-white rounded-lg hover:bg-amber-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
						>
							{retryingRunId === selectedRunDetail.id
								? ($t.translate?.run?.retrying || 'Retrying...')
								: ($t.translate?.run?.retry_failed || 'Retry Failed')}
						</button>
					{/if}
				</div>

				<!-- Config Snapshot -->
				{#if selectedRunDetail.config_snapshot}
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-700 mb-2">{$t.translate?.history?.config_snapshot}</h3>
						<div class="bg-gray-50 rounded-lg p-3">
							<pre class="text-xs text-gray-600 overflow-x-auto">{JSON.stringify(selectedRunDetail.config_snapshot, null, 2)}</pre>
						</div>
					</div>
				{/if}

				<!-- Hash info -->
				{#if selectedRunDetail.config_hash || selectedRunDetail.dict_snapshot_hash}
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-700 mb-2">{$t.translate?.history?.snapshots}</h3>
						<div class="grid grid-cols-3 gap-2 text-xs font-mono text-gray-500">
							{#if selectedRunDetail.config_hash}
								<div class="bg-gray-50 rounded p-2">Config: {selectedRunDetail.config_hash}</div>
							{/if}
							{#if selectedRunDetail.dict_snapshot_hash}
								<div class="bg-gray-50 rounded p-2">Dict: {selectedRunDetail.dict_snapshot_hash}</div>
							{/if}
							{#if selectedRunDetail.key_hash}
								<div class="bg-gray-50 rounded p-2">Key: {selectedRunDetail.key_hash}</div>
							{/if}
						</div>
					</div>
				{/if}

				<!-- Events -->
				{#if selectedRunDetail.events && selectedRunDetail.events.length > 0}
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-700 mb-2">{$t.translate?.history?.events.replace('{count}', selectedRunDetail.events.length)}</h3>
						<div class="space-y-1 max-h-48 overflow-y-auto">
							{#each selectedRunDetail.events as evt}
								<div class="flex items-center gap-2 text-xs text-gray-600 bg-gray-50 rounded px-2 py-1">
									<span class="font-medium text-gray-800">{evt.event_type}</span>
									<span class="text-gray-400">|</span>
									<span>{evt.created_at ? new Date(evt.created_at).toLocaleString() : ''}</span>
								</div>
							{/each}
						</div>
					</div>
				{/if}

				<!-- Error -->
				{#if selectedRunDetail.error_message}
					<div class="bg-destructive-light border border-destructive-light rounded-lg p-3 mb-6">
						<p class="text-xs font-medium text-red-700">{$t.translate?.history?.error}</p>
						<p class="text-xs text-red-600 mt-1">{selectedRunDetail.error_message}</p>
					</div>
				{/if}

				<!-- Superset ref -->
				{#if selectedRunDetail.superset_execution_id}
					<div class="bg-primary-light rounded-lg p-3 mb-6">
						<p class="text-xs font-medium text-blue-700">{$t.translate?.history?.superset_query_id}</p>
						<p class="text-xs font-mono text-blue-600 mt-1">{selectedRunDetail.superset_execution_id}</p>
					</div>
				{/if}
			</div>
		</div>
	{/if}
</div>
<!-- #endregion TranslateHistoryPage -->
