<script lang="ts">
	import {
		coreTasksApi,
		type UnifiedTask,
		type UnifiedTaskDetail,
		type UnifiedTaskStatus
	} from '$lib/api/dashboard/a76/tasks';
	import { companyStore } from '$lib/stores/company.svelte';
	import { Button } from '$lib/components/ui/button';
	import { Input } from '$lib/components/ui/input';
	import * as Select from '$lib/components/ui/select';
	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 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 || 'Error cargando tareas';
			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, string> = {
			pending: 'En cola',
			active: 'En progreso',
			completed: 'Completada',
			failed: 'Fallida'
		};
		return map[status] ?? 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 || 'No se pudo sincronizar el detalle';
			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 space-y-4">
	<div class="flex flex-none items-center justify-end">
		<Button onclick={() => void loadTasks(true)} disabled={loading}>
			{loading ? 'Cargando...' : 'Refrescar'}
		</Button>
	</div>

	<div class="grid grid-cols-1 gap-3 md:grid-cols-3">
		<Input placeholder="Buscar por task_id / nombre / error" bind:value={search} />
		<Select.Root type="single" bind:value={statusFilter}>
			<Select.Trigger><Select.Value placeholder="Estado" /></Select.Trigger>
			<Select.Content>
				<Select.Item value="all">Todos</Select.Item>
				<Select.Item value="pending">En cola</Select.Item>
				<Select.Item value="active">En progreso</Select.Item>
				<Select.Item value="completed">Completadas</Select.Item>
				<Select.Item value="failed">Fallidas</Select.Item>
			</Select.Content>
		</Select.Root>
		<Button variant="outline" onclick={applyFilters}>Aplicar filtros</Button>
	</div>

	{#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="min-h-0 flex-1 overflow-auto rounded-md border">
		<table class="w-full text-sm">
			<thead class="bg-muted/40">
				<tr>
					<th class="p-2 text-left">Task ID</th>
					<th class="p-2 text-left">Tipo</th>
					<th class="p-2 text-left">Empresa</th>
					<th class="p-2 text-left">Estado</th>
					<th class="p-2 text-left">Progreso</th>
					<th class="p-2 text-left">Reintentos</th>
					<th class="p-2 text-left">Actualizado</th>
				</tr>
			</thead>
			<tbody>
				{#if tasks.length === 0 && !loading}
					<tr>
						<td class="p-4 text-center text-muted-foreground" colspan="7">Sin tareas registradas</td>
					</tr>
				{:else if tasks.length === 0 && loading}
					<tr>
						<td class="p-4 text-center text-muted-foreground italic" colspan="7">Cargando...</td>
					</tr>
				{:else}
					{#each tasks as task}
						<tr
							class="cursor-pointer border-t hover:bg-muted/20 {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">{task.task_group} / {task.task_name}</td>
							<td class="p-2 text-muted-foreground">{task.company_id ?? '—'}</td>
							<td class={`p-2 font-medium ${statusClass(task.status)}`}>
								{statusLabel(task.status)}
								<span class="ml-1 text-xs font-normal text-muted-foreground"
									>({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>

	<div class="flex flex-none items-center justify-between text-sm">
		<div class="text-muted-foreground">Total: {total}</div>
		<div class="flex items-center gap-2">
			<Button
				variant="outline"
				disabled={page <= 1 || loading}
				onclick={() => {
					page -= 1;
					void loadTasks(false);
				}}>Anterior</Button>
			<span>Página {page}</span>
			<Button
				variant="outline"
				disabled={page * pageSize >= total || loading}
				onclick={() => {
					page += 1;
					void loadTasks(false);
				}}>Siguiente</Button>
		</div>
	</div>
</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>Detalle de tarea</Dialog.Title>
			<Dialog.Description>
				{#if detailLoading}
					Sincronizando estado con Celery…
				{:else if selectedDetail}
					<span class="font-mono text-xs">{selectedDetail.task_id}</span>
				{:else}
					Cargando…
				{/if}
			</Dialog.Description>
		</Dialog.Header>

		{#if detailLoading}
			<div class="flex items-center gap-2 py-4">
				<Badge variant="secondary">Sincronizando…</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>Task:</strong>
					<span class="ml-1 font-mono text-xs">{selectedDetail.task_id}</span>
				</div>
				<div>
					<strong>Estado:</strong>
					<span class={statusClass(selectedDetail.status)}>{statusLabel(selectedDetail.status)}</span>
					<span class="text-muted-foreground">({selectedDetail.celery_state_raw})</span>
				</div>
				<div>
					<strong>Progreso:</strong>
					{formatPercent(selectedDetail)}
					{#if selectedDetail.progress?.message}
						— {selectedDetail.progress.message}
					{/if}
				</div>
				<div><strong>Origen:</strong> {selectedDetail.task_origin || '—'}</div>
				<div><strong>Solicitante:</strong> {selectedDetail.requested_by_user || '—'}</div>
				<div>
					<strong>Error:</strong>
					{selectedDetail.error?.type || '—'} — {selectedDetail.error?.message || '—'}
				</div>
				{#if selectedDetail.started_at}
					<div><strong>Inicio:</strong> {new Date(selectedDetail.started_at).toLocaleString()}</div>
				{/if}
				{#if selectedDetail.finished_at}
					<div><strong>Fin:</strong> {new Date(selectedDetail.finished_at).toLocaleString()}</div>
				{/if}
				{#if selectedDetail.traceback_excerpt}
					<div>
						<strong class="block">Traceback (extracto)</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">Resultado (resumen)</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}>Cerrar</Button>
		</Dialog.Footer>
	</Dialog.Content>
</Dialog.Root>
