<script lang="ts">
	import { page } from '$app/stores';
	import { goto } from '$app/navigation';
	import { browser } from '$app/environment';
	import { toast } from 'svelte-sonner';
	import { m } from '$lib/i18n/messages';
	import {
		Plus,
		RefreshCw,
		Pencil,
		Trash2,
		Search,
		RotateCcw,
		Send,
		Loader2,
		FileSpreadsheet,
		Table
	} from 'lucide-svelte';
	import * as Card from '$lib/components/ui/card';
	import * as Select from '$lib/components/ui/select';
	import { Button } from '$lib/components/ui/button';
	import { Input } from '$lib/components/ui/input';
	import { Separator } from '$lib/components/ui/separator';
	import { companyStore } from '$lib/stores/company.svelte';
	import { currentUser } from '$lib/auth';
	import { userHasDodaCatalogAction } from '$lib/permissions/catalogs/doda-permissions';
	import ErrorState from '$lib/components/dashboard/common/error-state.svelte';
	import { isPitaCustomsClearance } from '$lib/components/dashboard/general_catalogs/doda/doda-form-helpers';

	import DataTable from '$lib/components/dashboard/general_catalogs/doda/data-table.svelte';
	import { createColumns } from '$lib/components/dashboard/general_catalogs/doda/columns';
	import DodaProgressDialog from '$lib/components/dashboard/despacho/doda/doda-progress-dialog.svelte';
	import DodaExportExcelDialog from '$lib/components/dashboard/despacho/doda/doda-export-excel-dialog.svelte';
	import DodaFormModal from '$lib/components/dashboard/general_catalogs/doda/doda-form-modal.svelte';
	import { applyOptimisticDelete } from '$lib/components/dashboard/general_catalogs/doda/delete-list-state';

	import {
		getDodas,
		deleteDoda,
		exportDodaPedimentosDetail,
		postDodaAlta,
		postDodaConsulta,
		postDodaConsultaApply,
		postDodaEliminar,
		getDodaAltaStatus,
		getDodaElegibilidad,
		getDodaConsultaStatus,
		getDodaEliminarStatus,
		type DodaAltaStatusResponse,
		type Doda
	} from '$lib/api/dashboard/a76/general_catalogs/doda';

	let { data } = $props();

	let allDodas = $state<Doda[]>(data.dodas?.items || []);
	let dodaPage = $state(data.dodas?.page || 1);
	let dodaPageSize = $state(50);
	let dodaTotal = $state(data.dodas?.total || 0);
	let dodaLoading = $state(false);
	let dodaHasMore = $derived(allDodas.length < dodaTotal);

	let filters = $state({
		integration_number: $page.url.searchParams.get('integration_number') || '',
		patent: $page.url.searchParams.get('patent') || '',
		status: $page.url.searchParams.get('status') || '',
		operation_type: $page.url.searchParams.get('operation_type') || ''
	});

	let dodaFilterTimeout: ReturnType<typeof setTimeout>;

	let selectedDodaIds = $state<(string | number)[]>([]);
	const selectedDoda = $derived(
		selectedDodaIds.length === 1
			? allDodas.find((item) => String(item.id) === String(selectedDodaIds[0])) ?? null
			: null
	);
	const altaVariant = $derived<'doda' | 'pita'>(
		selectedDoda && isPitaCustomsClearance(selectedDoda.customs_clearance) ? 'pita' : 'doda'
	);

	let progressDialogOpen = $state(false);
	let exportDialogOpen = $state(false);
	let currentTaskId = $state('');
	let currentVariant = $state<'doda' | 'pita'>('doda');
	let progressMode = $state<'alta' | 'consulta' | 'eliminar'>('alta');
	let altaLoading = $state(false);
	let consultaLoading = $state(false);
	let eliminarExternoLoading = $state(false);
	let deleteLoading = $state(false);
	let pedimentosExportLoading = $state(false);
	const hasIntegration = $derived(!!(selectedDoda?.integration_number || '').trim());
	const canView = $derived(userHasDodaCatalogAction($currentUser, 'view'));
	const canCreate = $derived(userHasDodaCatalogAction($currentUser, 'create'));
	const canEdit = $derived(userHasDodaCatalogAction($currentUser, 'edit'));
	const canDelete = $derived(userHasDodaCatalogAction($currentUser, 'delete'));
	const accessDeniedMessage = $derived(!canView ? 'Permission denied: cat_doda.view' : null);
	const activeDodaIdParam = $derived($page.url.searchParams.get('doda_id'));
	const modalCanMutate = $derived(activeDodaIdParam === 'new' ? canCreate : canEdit);

	$effect(() => {
		if (data.dodas) {
			allDodas = data.dodas.items || [];
			dodaPage = data.dodas.page || 1;
			dodaTotal = data.dodas.total || 0;
		}
	});

	$effect(() => {
		const _ = { ...filters };
		clearTimeout(dodaFilterTimeout);
		dodaFilterTimeout = setTimeout(() => reloadDodas(), 400);
	});

	async function reloadDodas() {
		if (!browser) return;
		dodaLoading = true;
		try {
			const companyId = companyStore.activeCompany?.id;
			if (!companyId) return;
			const active = Object.fromEntries(Object.entries(filters).filter(([, v]) => v !== ''));
			const res = await getDodas(1, dodaPageSize, active, Number(companyId));
			if (res.data) {
				allDodas = res.data.items;
				dodaPage = 1;
				dodaTotal = res.data.total;
				selectedDodaIds = [];
			}
		} catch {
			if (allDodas.length > 0) toast.error('Error al recargar DODAs');
		} finally {
			dodaLoading = false;
		}
	}

	async function loadMoreDodas() {
		if (dodaLoading || !dodaHasMore) return;
		dodaLoading = true;
		try {
			const companyId = companyStore.activeCompany?.id;
			if (!companyId) return;
			const active = Object.fromEntries(Object.entries(filters).filter(([, v]) => v !== ''));
			const res = await getDodas(dodaPage + 1, dodaPageSize, active, Number(companyId));
			if (res.data) {
				allDodas = [...allDodas, ...res.data.items];
				dodaPage++;
				dodaTotal = res.data.total;
			}
		} finally {
			dodaLoading = false;
		}
	}

	function handleNew() {
		if (!canCreate) return;
		const url = new URL($page.url);
		url.searchParams.set('doda_id', 'new');
		goto(url.toString(), { replaceState: true });
	}

	function handleEdit() {
		if (!canEdit) return;
		if (!selectedDoda) return;
		const url = new URL($page.url);
		url.searchParams.set('doda_id', String(selectedDoda.id));
		goto(url.toString(), { replaceState: true });
	}

	async function handleDelete() {
		if (!canDelete) return;
		if (deleteLoading) return;
		if (!companyStore.activeCompany) {
			toast.error(m['sidebar.doda_alta.delete_missing_company']());
			return;
		}
		if (selectedDodaIds.length !== 1) {
			toast.error(m['sidebar.doda_alta.delete_select_one']());
			return;
		}
		if (!selectedDoda) {
			toast.error(m['sidebar.doda_alta.delete_not_found']());
			return;
		}
		if (!confirm(m['sidebar.doda_alta.confirm_delete']())) return;
		deleteLoading = true;
		try {
			const deletedId = selectedDoda.id;
			await deleteDoda(deletedId, companyStore.activeCompany.id);
			toast.success(m['sidebar.doda_alta.delete_success']());
			const next = applyOptimisticDelete(allDodas, dodaTotal, deletedId);
			allDodas = next.items;
			dodaTotal = next.total;
			selectedDodaIds = [];
			await reloadDodas();
		} catch (e) {
			const msg = e instanceof Error ? e.message : m['sidebar.doda_alta.delete_error']();
			toast.error(msg);
		} finally {
			deleteLoading = false;
		}
	}

	async function handleExportPedimentos() {
		if (pedimentosExportLoading) return;
		if (!companyStore.activeCompany) {
			toast.error(m['sidebar.doda_alta.delete_missing_company']());
			return;
		}
		if (selectedDodaIds.length !== 1 || !selectedDoda) {
			toast.error(m['sidebar.doda_alta.delete_select_one']());
			return;
		}
		pedimentosExportLoading = true;
		try {
			await exportDodaPedimentosDetail(selectedDoda.id, companyStore.activeCompany.id, 'xls');
			toast.success(m['sidebar.doda_alta.export_pedimentos_success']());
		} catch (e) {
			const msg = e instanceof Error ? e.message : m['sidebar.doda_alta.export_pedimentos_error']();
			toast.error(msg || m['sidebar.doda_alta.export_pedimentos_error']());
		} finally {
			pedimentosExportLoading = false;
		}
	}

	function clearFilters() {
		filters = { integration_number: '', patent: '', status: '', operation_type: '' };
	}

	async function handleAlta() {
		if (!canEdit) return;
		if (!selectedDoda || !companyStore.activeCompany) return;
		const companyId = companyStore.activeCompany.id;
		const dodaId = selectedDoda.id;
		const variant = altaVariant;
		altaLoading = true;
		try {
			const elig = await getDodaElegibilidad(dodaId, companyId, variant);
			if (elig.error) {
				toast.error(`Error al verificar elegibilidad: ${elig.error}`);
				return;
			}
			if (elig.data && !elig.data.can_alta) {
				const msgs = elig.data.reasons.map((r) => `• ${r.message}`).join('\n');
				toast.error(msgs || m['sidebar.doda_alta.eligibility_error']());
				return;
			}
			const resp = await postDodaAlta(dodaId, companyId, variant);
			if (resp.error) {
				toast.error(`Error al enviar alta: ${resp.error}`);
				return;
			}
			currentTaskId = resp.data!.task_id;
			currentVariant = variant;
			progressDialogOpen = true;
		} finally {
			altaLoading = false;
		}
	}

	async function handleConsultar() {
		if (!canEdit) return;
		if (!selectedDoda || !companyStore.activeCompany || consultaLoading) return;
		if (!hasIntegration) {
			toast.error('El DODA aún no está generado para consultar.');
			return;
		}
		consultaLoading = true;
		try {
			const resp = await postDodaConsulta(selectedDoda.id, companyStore.activeCompany.id, altaVariant);
			if (resp.error || !resp.data?.task_id) {
				toast.error(resp.error || 'Error al enviar consulta DODA');
				return;
			}
			progressMode = 'consulta';
			currentTaskId = resp.data.task_id;
			currentVariant = altaVariant;
			progressDialogOpen = true;
		} finally {
			consultaLoading = false;
		}
	}

	async function handleEliminarExterno() {
		if (!canDelete) return;
		if (!selectedDoda || !companyStore.activeCompany || eliminarExternoLoading) return;
		if (!hasIntegration) {
			toast.error('El DODA aún no está generado para eliminar externamente.');
			return;
		}
		if (!confirm('¿Deseas eliminar este DODA en el servicio externo para volver a editarlo?')) return;
		eliminarExternoLoading = true;
		try {
			const resp = await postDodaEliminar(selectedDoda.id, companyStore.activeCompany.id, altaVariant);
			if (resp.error || !resp.data?.task_id) {
				toast.error(resp.error || 'Error al enviar eliminación DODA');
				return;
			}
			progressMode = 'eliminar';
			currentTaskId = resp.data.task_id;
			currentVariant = altaVariant;
			progressDialogOpen = true;
		} finally {
			eliminarExternoLoading = false;
		}
	}

	async function onProgressComplete(_result: DodaAltaStatusResponse) {
		progressDialogOpen = false;
		if (progressMode === 'consulta' && selectedDoda && companyStore.activeCompany) {
			const applyResp = await postDodaConsultaApply(
				selectedDoda.id,
				currentTaskId,
				companyStore.activeCompany.id
			);
			if (applyResp.error) {
				toast.error(`Consulta completada, pero no se pudo aplicar al DODA: ${applyResp.error}`);
			}
		}
		await reloadDodas();
		if (progressMode === 'eliminar') {
			toast.success('Eliminación DODA completada. El registro quedó editable nuevamente.');
		} else if (progressMode === 'consulta') {
			toast.success('Consulta DODA completada y aplicada al registro.');
		} else {
			toast.success(m['sidebar.doda_alta.progress_success']());
		}
	}

	const progressTitle = $derived(
		progressMode === 'consulta'
			? 'Consulta DODA'
			: progressMode === 'eliminar'
				? 'Eliminación DODA'
				: m['sidebar.doda_alta.progress_title']()
	);
	const progressDescription = $derived(
		progressMode === 'consulta'
			? 'Consulta'
			: progressMode === 'eliminar'
				? 'Eliminación'
				: 'Alta'
	);
	const progressStatusGetter = $derived(
		progressMode === 'consulta'
			? getDodaConsultaStatus
			: progressMode === 'eliminar'
				? getDodaEliminarStatus
				: getDodaAltaStatus
	);
</script>

{#if accessDeniedMessage}
	<div class="p-6">
		<ErrorState status={403} error={accessDeniedMessage} />
	</div>
{:else}
<div class="flex flex-col gap-6 p-6 h-[calc(100svh-4rem)] group-has-data-[collapsible=icon]/sidebar-wrapper:h-[calc(100svh-3rem)] overflow-hidden">
	<div class="flex-none flex items-center justify-between">
		<div class="space-y-1">
			<h1 class="text-2xl font-bold tracking-tight">{m['sidebar.doda_alta.title']()}</h1>
			<p class="text-muted-foreground">{m['sidebar.doda_alta.subtitle']()}</p>
		</div>
		<div class="flex items-center gap-3">
			<Button variant="outline" size="sm" onclick={() => reloadDodas()} disabled={dodaLoading}>
				<RefreshCw class="mr-2 h-4 w-4 {dodaLoading ? 'animate-spin' : ''}" />
				{m['sidebar.doda_alta.refresh']()}
			</Button>
			<Button size="sm" onclick={handleNew} disabled={!canCreate}>
				<Plus class="mr-2 h-4 w-4" />
				{m['sidebar.doda_alta.action_new']()}
			</Button>
		</div>
	</div>

	<Card.Root class="flex min-h-0 flex-1 flex-col border bg-background">
		<Card.Header>
			<div class="flex flex-col gap-3 xl:flex-row xl:items-center xl:justify-between">
				<Card.Title>{m['sidebar.doda_alta.table_title']()}</Card.Title>
				<div class="grid gap-2 sm:grid-cols-2 xl:grid-cols-[220px_180px_170px_170px_auto] xl:items-center">
					<div class="relative">
						<Search class="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
						<Input
							placeholder={m['sidebar.doda_alta.filter_integration_number']()}
							bind:value={filters.integration_number}
							class="h-9 bg-card pl-9"
						/>
					</div>
					<Input
						placeholder={m['sidebar.doda_alta.filter_patent']()}
						bind:value={filters.patent}
						class="h-9 bg-card"
					/>
					<Select.Root
						type="single"
						value={filters.status}
						onValueChange={(v) => (filters.status = v)}
					>
						<Select.Trigger class="h-9 w-full bg-card">
							{filters.status || m['sidebar.doda_alta.filter_status']()}
						</Select.Trigger>
						<Select.Content>
							<Select.Item value="">Todos</Select.Item>
							<Select.Item value="PENDIENTE">PENDIENTE</Select.Item>
							<Select.Item value="GENERADO">GENERADO</Select.Item>
							<Select.Item value="VALIDADO">VALIDADO</Select.Item>
							<Select.Item value="ELIMINADO">ELIMINADO</Select.Item>
						</Select.Content>
					</Select.Root>
					<Select.Root
						type="single"
						value={filters.operation_type}
						onValueChange={(v) => (filters.operation_type = v)}
					>
						<Select.Trigger class="h-9 w-full bg-card">
							{filters.operation_type === 'I'
								? 'Importación'
								: filters.operation_type === 'E'
									? 'Exportación'
									: m['sidebar.doda_alta.filter_operation_type']()}
						</Select.Trigger>
						<Select.Content>
							<Select.Item value="">Todas</Select.Item>
							<Select.Item value="I">I - Importación</Select.Item>
							<Select.Item value="E">E - Exportación</Select.Item>
						</Select.Content>
					</Select.Root>
					<Button variant="outline" size="sm" class="h-9" onclick={clearFilters}>
						<RotateCcw class="mr-2 h-4 w-4" />
						Limpiar
					</Button>
				</div>
			</div>
		</Card.Header>
		<Card.Content class="min-h-0 p-0">
			<div class="rounded-md border bg-background">
				<DataTable
					data={allDodas}
					columns={createColumns('es', () => reloadDodas())}
					loading={dodaLoading}
					hasMore={dodaHasMore}
					loadMore={loadMoreDodas}
					selectedId={selectedDodaIds.length === 1 ? selectedDodaIds[0] : null}
					onRowClick={(row) => {
						selectedDodaIds = selectedDodaIds.includes(row.id) ? [] : [row.id];
					}}
					onRowDoubleClick={(item) => {
						const url = new URL($page.url);
						url.searchParams.set('doda_id', String(item.id));
						goto(url.toString(), { replaceState: true });
					}}
				/>
			</div>
		</Card.Content>
	</Card.Root>

	<div class="flex-none text-sm text-muted-foreground pt-2">
		Mostrando {allDodas.length} de {dodaTotal} registros
		<span class="ml-2">•</span>
		<span class="ml-2">Filtros activos: {Object.values(filters).filter((v) => v !== '').length}</span>
	</div>

	<div class="h-20"></div>

	<div
		class="fixed right-0 bottom-0 left-0 z-50 ml-[calc(var(--sidebar-width))] border-t bg-background/95 shadow-lg backdrop-blur group-has-data-[state=collapsed]/sidebar-wrapper:ml-[calc(var(--sidebar-width-icon))] supports-[backdrop-filter]:bg-background/80"
	>
		<div class="mx-auto max-w-[1400px] px-4 py-4">
			<div class="flex flex-wrap justify-end gap-2">
				<Button
					variant="outline"
					size="sm"
					onclick={handleEdit}
					disabled={!canEdit || selectedDodaIds.length !== 1 || hasIntegration}
				>
					<Pencil size={16} class="mr-2" />
					{m['sidebar.doda_alta.action_edit']()}
				</Button>
				<Button
					size="sm"
					variant="secondary"
					onclick={handleConsultar}
					disabled={!canEdit || selectedDodaIds.length !== 1 || !hasIntegration || consultaLoading}
				>
					{#if consultaLoading}
						<Loader2 size={16} class="mr-2 animate-spin" />
					{:else}
						<Search size={16} class="mr-2" />
					{/if}
					Consultar DODA
				</Button>
				<Button
					size="sm"
					variant="secondary"
					class="border border-amber-500/30 bg-amber-500/10 text-amber-700 hover:bg-amber-500/20"
					onclick={handleEliminarExterno}
					disabled={!canDelete || selectedDodaIds.length !== 1 || !hasIntegration || eliminarExternoLoading}
				>
					{#if eliminarExternoLoading}
						<Loader2 size={16} class="mr-2 animate-spin" />
					{:else}
						<Trash2 size={16} class="mr-2" />
					{/if}
					Eliminar DODA
				</Button>
				<Button
					variant="outline"
					size="sm"
					onclick={handleDelete}
					disabled={!canDelete || selectedDodaIds.length !== 1 || deleteLoading}
					class="text-destructive hover:bg-destructive/10 hover:text-destructive"
				>
					{#if deleteLoading}
						<Loader2 size={16} class="mr-2 animate-spin" />
					{:else}
						<Trash2 size={16} class="mr-2" />
					{/if}
					{m['sidebar.doda_alta.action_delete']()}
				</Button>
				<Button variant="outline" size="sm" onclick={() => (exportDialogOpen = true)}>
					<FileSpreadsheet size={16} class="mr-2" />
					{m['sidebar.doda_alta.action_export_excel']()}
				</Button>
				<Button
					size="sm"
					variant="secondary"
					class="border border-primary/25 bg-primary/10 text-primary hover:bg-primary/15"
					onclick={handleExportPedimentos}
					disabled={selectedDodaIds.length !== 1 || pedimentosExportLoading || !companyStore.activeCompany}
					title={m['sidebar.doda_alta.action_export_pedimentos']()}
				>
					{#if pedimentosExportLoading}
						<Loader2 size={16} class="mr-2 animate-spin" />
					{:else}
						<Table size={16} class="mr-2" />
					{/if}
					{m['sidebar.doda_alta.action_export_pedimentos']()}
				</Button>
				<Separator orientation="vertical" class="mx-1 h-8 hidden sm:block" />
				<Button
					size="sm"
					onclick={handleAlta}
					disabled={!canEdit || selectedDodaIds.length !== 1 || altaLoading || hasIntegration}
					title={altaVariant === 'pita' ? 'PITA' : 'DODA'}
				>
					{#if altaLoading}
						<Loader2 size={16} class="mr-2 animate-spin" />
					{:else}
						<Send size={16} class="mr-2" />
					{/if}
					{m['sidebar.doda_alta.action_generar']()}
				</Button>
			</div>
		</div>
	</div>
</div>

<DodaExportExcelDialog bind:open={exportDialogOpen} companyId={companyStore.activeCompany?.id} />

{#if progressDialogOpen}
	<DodaProgressDialog
		bind:open={progressDialogOpen}
		taskId={currentTaskId}
		dodaId={selectedDoda?.id}
		variant={currentVariant}
		title={progressTitle}
		description={progressDescription}
		getStatus={progressStatusGetter}
		onComplete={onProgressComplete}
		onCancel={() => (progressDialogOpen = false)}
	/>
{/if}

{#if $page.url.searchParams.get('doda_id')}
	<DodaFormModal
		dodaIdParam={$page.url.searchParams.get('doda_id')!}
		defaultLastUser={data.defaultLastUser}
		canMutate={modalCanMutate}
		onClose={() => {
			const url = new URL($page.url);
			url.searchParams.delete('doda_id');
			goto(url.toString(), { replaceState: true });
			void reloadDodas();
		}}
		onCreatedNavigateTo={(newId) => {
			const url = new URL($page.url);
			url.searchParams.set('doda_id', String(newId));
			goto(url.toString(), { replaceState: true });
		}}
	/>
{/if}
{/if}
