<script lang="ts">
	import { getLocale } from '$lib/paraglide/runtime';
	import {
		coreTasksApi,
		type UnifiedTask,
		type UnifiedTaskDetail,
		type UnifiedTaskStatus
	} from '$lib/api/dashboard/a76/tasks';
	import { companyStore } from '$lib/stores/company.svelte';
	import { translateCeleryState, translateTaskGroup, translateTaskName } from '$lib/utils/audit-log-i18n';
	import * as Card from '$lib/components/ui/card';
	import { Button } from '$lib/components/ui/button';
	import { Input } from '$lib/components/ui/input';
	import * as Dialog from '$lib/components/ui/dialog';
	import { Badge } from '$lib/components/ui/badge';

	let loading = $state(false);
	let detailOpen = $state(false);
	let error = $state<string | null>(null);
	let tasks = $state<UnifiedTask[]>([]);
	let total = $state(0);
	let page = $state(1);
	const pageSize = 50;
	let search = $state('');
	let statusFilter = $state<UnifiedTaskStatus | 'all'>('all');
	let selectedDetail = $state<UnifiedTaskDetail | null>(null);
	let detailLoading = $state(false);
	let detailError = $state<string | null>(null);
	let pollTimer: ReturnType<typeof setInterval> | null = null;

	function isSpanish() {
		return getLocale() === 'es';
	}

	function text(es: string, en: string) {
		return isSpanish() ? es : en;
	}

	function hasActive(items: UnifiedTask[]) {
		return items.some((x) => x.status === 'pending' || x.status === 'active');
	}

	function mergeListIntoDetail(items: UnifiedTask[]) {
		if (!selectedDetail) return;
		const row = items.find((x) => x.task_id === selectedDetail!.task_id);
		if (!row) return;
		selectedDetail = {
			...selectedDetail,
			...row,
			traceback_excerpt: selectedDetail.traceback_excerpt,
			result_summary: selectedDetail.result_summary,
			meta_payload: selectedDetail.meta_payload
		};
	}

	async function loadTasks(syncActive = true) {
		loading = true;
		error = null;
		const response = await coreTasksApi.list({
			page,
			page_size: pageSize,
			search: search.trim() || undefined,
			status: statusFilter === 'all' ? undefined : [statusFilter],
			company_id: companyStore.activeCompany?.id,
			sync_active: syncActive
		});

		if (response.error || !response.data) {
			error = response.error || text('Error cargando tareas', 'Error loading tasks');
			loading = false;
			return;
		}
		tasks = response.data.items || [];
		total = response.data.total || 0;
		loading = false;
		mergeListIntoDetail(tasks);
		setupPolling();
	}

	function setupPolling() {
		if (pollTimer) clearInterval(pollTimer);
		pollTimer = null;
		if (hasActive(tasks)) {
			pollTimer = setInterval(() => void loadTasks(true), 7000);
		}
	}

	function applyFilters() {
		page = 1;
		void loadTasks(true);
	}

	function statusLabel(status: string): string {
		const map: Record<string, { en: string; es: string }> = {
			pending: { en: 'Queued', es: 'En cola' },
			active: { en: 'In progress', es: 'En progreso' },
			completed: { en: 'Completed', es: 'Completada' },
			failed: { en: 'Failed', es: 'Fallida' }
		};
		return map[status]?.[isSpanish() ? 'es' : 'en'] ?? status;
	}

	function statusClass(status: string) {
		if (status === 'completed') return 'text-green-600 dark:text-green-400';
		if (status === 'failed') return 'text-red-600 dark:text-red-400';
		if (status === 'active') return 'text-blue-600 dark:text-blue-400';
		return 'text-amber-600 dark:text-amber-400';
	}

	function formatPercent(t: UnifiedTask) {
		if (t.status === 'completed') {
			const p = t.progress?.percent;
			if (p != null && p > 0) return `${Math.round(p)}%`;
			if (t.progress?.current != null && t.progress?.total && t.progress.total > 0) {
				const ratio = (t.progress.current / t.progress.total) * 100;
				if (ratio > 0) return `${Math.round(ratio)}%`;
			}
			return '100%';
		}
		if (t.progress?.percent != null) return `${Math.round(t.progress.percent)}%`;
		if (t.progress?.current != null && t.progress?.total) {
			return `${Math.round((t.progress.current / t.progress.total) * 100)}%`;
		}
		return '—';
	}

	async function openDetail(t: UnifiedTask) {
		detailOpen = true;
		selectedDetail = { ...t } as UnifiedTaskDetail;
		detailLoading = true;
		detailError = null;
		const res = await coreTasksApi.get(t.task_id, true);
		if (!detailOpen) return;
		detailLoading = false;
		if (res.error || !res.data) {
			detailError = res.error || text('No se pudo sincronizar el detalle', 'Could not sync task details');
			return;
		}
		selectedDetail = res.data;
	}

	function closeDetail() {
		detailOpen = false;
		selectedDetail = null;
		detailError = null;
	}

	$effect(() => {
		const _cid = companyStore.activeCompany?.id;
		void _cid;
		page = 1;
		void loadTasks(true);
		return () => {
			if (pollTimer) clearInterval(pollTimer);
		};
	});
</script>

<div class="flex min-h-0 flex-1 flex-col gap-4">
	<Card.Root class="flex min-h-0 flex-1 flex-col overflow-hidden">
		<Card.Header class="flex-none py-3">
			<div class="flex items-center justify-between">
				<div>
					<Card.Title>{text('Tareas del Sistema', 'System Tasks')}</Card.Title>
					<Card.Description class="text-xs">{text(`Total: ${total} tareas encontradas`, `Total: ${total} tasks found`)}</Card.Description>
				</div>
				<div class="flex flex-wrap items-center gap-2">
					<Input placeholder={text('Buscar por task_id / nombre / error', 'Search by task_id / name / error')} bind:value={search} class="h-9 w-64" />
					<select
						bind:value={statusFilter}
						class="flex h-9 w-[160px] rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none"
						title={text('Estado', 'Status')}
					>
						<option value="all">{text('Estado: Todos', 'Status: All')}</option>
						<option value="pending">{statusLabel('pending')}</option>
						<option value="active">{statusLabel('active')}</option>
						<option value="completed">{statusLabel('completed')}</option>
						<option value="failed">{statusLabel('failed')}</option>
					</select>
					<Button variant="outline" size="sm" class="h-9" onclick={applyFilters}>{text('Aplicar Filtros', 'Apply Filters')}</Button>
					<Button size="sm" class="h-9" onclick={() => void loadTasks(true)} disabled={loading}>
						{loading ? text('Cargando...', 'Loading...') : text('Refrescar', 'Refresh')}
					</Button>
				</div>
			</div>
		</Card.Header>
		<Card.Content class="flex min-h-0 flex-1 flex-col p-0 px-6 pb-3">
			{#if error}
				<div class="flex-none rounded border border-red-300 bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-red-900 dark:bg-red-950/40 dark:text-red-300">
					{error}
				</div>
			{/if}

			<div class="relative min-h-0 flex-1 overflow-auto rounded-md border bg-card shadow-inner">
				<table class="w-full text-sm">
					<thead class="sticky top-0 z-10 bg-background/95 shadow-sm backdrop-blur-sm">
						<tr>
							<th class="p-2 text-left">{text('ID de tarea', 'Task ID')}</th>
							<th class="p-2 text-left">{text('Tipo', 'Type')}</th>
							<th class="p-2 text-left">{text('Estado', 'Status')}</th>
							<th class="p-2 text-left">{text('Progreso', 'Progress')}</th>
							<th class="p-2 text-left">{text('Reintentos', 'Retries')}</th>
							<th class="p-2 text-left">{text('Actualizado', 'Updated')}</th>
						</tr>
					</thead>
					<tbody>
						{#if tasks.length === 0 && !loading}
							<tr>
								<td class="p-4 text-center text-muted-foreground" colspan="6">{text('Sin tareas registradas', 'No tasks found')}</td>
							</tr>
						{:else if tasks.length === 0 && loading}
							<tr>
								<td class="p-4 text-center text-muted-foreground italic" colspan="6">{text('Cargando...', 'Loading...')}</td>
							</tr>
						{:else}
							{#each tasks as task}
								<tr
									class="cursor-pointer border-t transition-colors hover:bg-muted/50 {selectedDetail?.task_id === task.task_id
										? 'bg-muted/30'
										: ''}"
									onclick={() => void openDetail(task)}
								>
									<td class="p-2 font-mono text-xs">{task.task_id}</td>
									<td class="p-2">{translateTaskGroup(task.task_group)} / {translateTaskName(task.task_name)}</td>
									<td class={`p-2 font-medium ${statusClass(task.status)}`}>
										{statusLabel(task.status)}
										<span class="ml-1 text-xs font-normal text-muted-foreground"
										>({translateCeleryState(task.celery_state_raw)})</span
										>
									</td>
									<td class="p-2">
										{formatPercent(task)}
										{task.progress?.message ? ` · ${task.progress.message}` : ''}
									</td>
									<td class="p-2">{task.retries ?? 0}</td>
									<td class="p-2 whitespace-nowrap">{new Date(task.updated_at).toLocaleString()}</td>
								</tr>
							{/each}
						{/if}
					</tbody>
				</table>
			</div>
		</Card.Content>
		<div class="flex flex-none items-center justify-between px-6 pb-4 text-sm">
			<div class="text-muted-foreground">Total: {total}</div>
			<div class="flex items-center gap-2">
				<Button
					variant="outline"
					size="sm"
					disabled={page <= 1 || loading}
					onclick={() => {
						page -= 1;
						void loadTasks(false);
					}}>{text('Anterior', 'Previous')}</Button
				>
				<span>{text('Página', 'Page')} {page}</span>
				<Button
					variant="outline"
					size="sm"
					disabled={page * pageSize >= total || loading}
					onclick={() => {
						page += 1;
						void loadTasks(false);
					}}>{text('Siguiente', 'Next')}</Button
				>
			</div>
		</div>
	</Card.Root>
</div>

<Dialog.Root
	bind:open={detailOpen}
	onOpenChange={(open) => {
		if (!open) closeDetail();
	}}
>
	<Dialog.Content class="max-h-[70vh] min-h-[320px] w-full max-w-xl overflow-y-auto sm:max-w-xl">
		<Dialog.Header>
			<Dialog.Title>{text('Detalle de tarea', 'Task Details')}</Dialog.Title>
			<Dialog.Description>
				{#if detailLoading}
					{text('Sincronizando estado con Celery…', 'Syncing state with Celery...')}
				{:else if selectedDetail}
					<span class="font-mono text-xs">{selectedDetail.task_id}</span>
				{:else}
					{text('Cargando…', 'Loading...')}
				{/if}
			</Dialog.Description>
		</Dialog.Header>

		{#if detailLoading}
			<div class="flex items-center gap-2 py-4">
				<Badge variant="secondary">{text('Sincronizando…', 'Syncing...')}</Badge>
			</div>
		{/if}

		{#if detailError}
			<p class="text-sm text-red-600 dark:text-red-400">{detailError}</p>
		{/if}

		{#if selectedDetail}
			<div class="space-y-2 text-sm">
				<div>
				<strong>{text('Tarea', 'Task')}:</strong>
					<span class="ml-1 font-mono text-xs">{selectedDetail.task_id}</span>
				</div>
				<div>
					<strong>{text('Estado', 'Status')}:</strong>
					<span class={statusClass(selectedDetail.status)}>{statusLabel(selectedDetail.status)}</span>
					<span class="text-muted-foreground">({translateCeleryState(selectedDetail.celery_state_raw)})</span>
				</div>
				<div>
					<strong>{text('Progreso', 'Progress')}:</strong>
					{formatPercent(selectedDetail)}
					{#if selectedDetail.progress?.message}
						— {selectedDetail.progress.message}
					{/if}
				</div>
				<div><strong>{text('Origen', 'Origin')}:</strong> {selectedDetail.task_origin || '—'}</div>
				<div><strong>{text('Solicitante', 'Requested by')}:</strong> {selectedDetail.requested_by_user || '—'}</div>
				<div>
					<strong>{text('Error', 'Error')}:</strong>
					{selectedDetail.error?.type || '—'} — {selectedDetail.error?.message || '—'}
				</div>
				{#if selectedDetail.started_at}
					<div><strong>{text('Inicio', 'Started')}:</strong> {new Date(selectedDetail.started_at).toLocaleString(isSpanish() ? 'es-MX' : 'en-US')}</div>
				{/if}
				{#if selectedDetail.finished_at}
					<div><strong>{text('Fin', 'Finished')}:</strong> {new Date(selectedDetail.finished_at).toLocaleString(isSpanish() ? 'es-MX' : 'en-US')}</div>
				{/if}
				{#if selectedDetail.traceback_excerpt}
					<div>
						<strong class="block">{text('Traceback (extracto)', 'Traceback (excerpt)')}</strong>
						<pre
							class="mt-1 max-h-48 overflow-auto rounded border bg-muted/50 p-2 text-xs whitespace-pre-wrap">{selectedDetail.traceback_excerpt}</pre>
					</div>
				{/if}
				{#if selectedDetail.result_summary && Object.keys(selectedDetail.result_summary).length > 0}
					<div>
						<strong class="block">{text('Resultado (resumen)', 'Result (summary)')}</strong>
						<pre
							class="mt-1 max-h-40 overflow-auto whitespace-pre-wrap break-words rounded border bg-muted/50 p-2 text-xs">{JSON.stringify(
								selectedDetail.result_summary,
								null,
								2
							)}</pre>
					</div>
				{/if}
			</div>
		{/if}

		<Dialog.Footer class="gap-2 sm:gap-0">
			<Button variant="outline" onclick={closeDetail}>{text('Cerrar', 'Close')}</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>
