<script lang="ts">
	import { onMount } from 'svelte';
	import { browser } from '$app/environment';
	import * as Sheet from '$lib/components/ui/sheet/index.js';
	import { Button } from '$lib/components/ui/button/index.js';
	import {
		CSV_IMPORT_PENDING_CHANGED,
		CSV_IMPORT_PENDING_KEY,
		type CsvImportPendingEntry,
		countCsvImportPendingForCompany,
		listCsvImportPendingForCompany,
		removeCsvImportPending,
		updateCsvImportPendingSnapshot
	} from '$lib/csv-import-pending';
	import { fetchCsvImportStatus, isWaitingConfirmationPayload } from '$lib/csv-import-status-api';
	import { Loader2, RefreshCw } from 'lucide-svelte';
	import { csvMsg } from '$lib/i18n/csv-msg';

	type ValidatedRow = CsvImportPendingEntry & { checking?: boolean };

	let {
		open = $bindable(false),
		companyId,
		onResume
	}: {
		open?: boolean;
		companyId: number | undefined;
		onResume: (entry: CsvImportPendingEntry, scanPayload: Record<string, unknown>) => void;
	} = $props();

	let rows = $state<ValidatedRow[]>([]);
	let refreshing = $state(false);
	let badgeCount = $state(0);

	function syncBadge() {
		badgeCount = companyId !== undefined ? countCsvImportPendingForCompany(companyId) : 0;
	}

	function profileLabel(p: CsvImportPendingEntry['profile']): string {
		const key = `pending.profiles.${p}` as const;
		const t = csvMsg(key);
		return t === key ? p : t;
	}

	function isStaleJob(status: number, err: string | undefined): boolean {
		if (status === 404) return true;
		const m = (err || '').toLowerCase();
		return /not found|no encontrado|404|expir|no disponible|invalid|inexistente/i.test(m);
	}

	async function validateAndLoad() {
		if (companyId === undefined) {
			rows = [];
			return;
		}
		refreshing = true;
		const raw = listCsvImportPendingForCompany(companyId);
		const next: ValidatedRow[] = [];
		for (const entry of raw) {
			const res = await fetchCsvImportStatus(entry.jobId, entry.profile);
			if (res.error && !res.data) {
				if (isStaleJob(res.status, res.error)) {
					removeCsvImportPending(entry.jobId);
					continue;
				}
				next.push({ ...entry, checking: false });
				continue;
			}
			if (res.data && isWaitingConfirmationPayload(res.data)) {
				const d = res.data as Record<string, unknown>;
				const tr = typeof d.total_rows === 'number' ? d.total_rows : undefined;
				const vr = typeof d.valid_rows === 'number' ? d.valid_rows : undefined;
				if (tr !== undefined || vr !== undefined) {
					updateCsvImportPendingSnapshot(entry.jobId, { totalRows: tr, validRows: vr });
				}
				const updated = { ...entry, totalRows: tr ?? entry.totalRows, validRows: vr ?? entry.validRows };
				next.push(updated);
			} else {
				removeCsvImportPending(entry.jobId);
			}
		}
		rows = next;
		refreshing = false;
		syncBadge();
	}

	$effect(() => {
		companyId;
		syncBadge();
	});

	$effect(() => {
		if (!browser || !open || companyId === undefined) return;
		void validateAndLoad();
	});

	onMount(() => {
		if (!browser) return;
		const onPending = () => {
			syncBadge();
			if (open && companyId !== undefined) void validateAndLoad();
		};
		const onStorage = (e: StorageEvent) => {
			if (e.key === CSV_IMPORT_PENDING_KEY) {
				syncBadge();
				if (open && companyId !== undefined) void validateAndLoad();
			}
		};
		window.addEventListener(CSV_IMPORT_PENDING_CHANGED, onPending);
		window.addEventListener('storage', onStorage);
		return () => {
			window.removeEventListener(CSV_IMPORT_PENDING_CHANGED, onPending);
			window.removeEventListener('storage', onStorage);
		};
	});

	function removeLocal(jobId: string) {
		removeCsvImportPending(jobId);
		rows = rows.filter((r) => r.jobId !== jobId);
		syncBadge();
	}
</script>

<Button variant="outline" size="sm" class="shrink-0" type="button" onclick={() => (open = true)}>
	{csvMsg('pending.badge')}
	{#if badgeCount > 0}
		<span class="ml-1.5 rounded-full bg-primary/15 px-2 py-0.5 text-xs font-semibold text-primary">
			{badgeCount}
		</span>
	{/if}
</Button>

<Sheet.Root bind:open>
	<Sheet.Content side="right" class="flex w-full max-w-lg flex-col sm:max-w-xl">
		<Sheet.Header>
			<Sheet.Title>{csvMsg('pending.title')}</Sheet.Title>
			<Sheet.Description>
				{csvMsg('pending.description')}
			</Sheet.Description>
		</Sheet.Header>
		<div class="flex items-center justify-end gap-2 border-b px-4 py-2">
			<Button variant="outline" size="sm" disabled={refreshing} onclick={() => void validateAndLoad()}>
				{#if refreshing}
					<Loader2 class="mr-2 h-4 w-4 animate-spin" />
				{:else}
					<RefreshCw class="mr-2 h-4 w-4" />
				{/if}
				{csvMsg('pending.refresh')}
			</Button>
		</div>
		<div class="min-h-0 flex-1 overflow-y-auto px-4 py-4">
			{#if rows.length === 0 && !refreshing}
				<p class="text-sm text-muted-foreground">{csvMsg('pending.empty')}</p>
			{:else if rows.length === 0 && refreshing}
				<p class="text-sm text-muted-foreground">{csvMsg('pending.checking')}</p>
			{:else}
				<ul class="space-y-3">
					{#each rows as row (row.jobId)}
						<li class="rounded-lg border border-border bg-card p-3 text-sm shadow-sm">
							<div class="font-medium text-foreground">
								{row.label || profileLabel(row.profile)}
							</div>
							<div class="mt-0.5 text-xs text-muted-foreground">{profileLabel(row.profile)}</div>
							{#if row.totalRows != null || row.validRows != null}
								<div class="mt-1 text-xs text-muted-foreground">
									{#if row.totalRows != null}
										{csvMsg('pending.total_rows')}: {row.totalRows}
									{/if}
									{#if row.validRows != null}
										<span class={row.totalRows != null ? ' · ' : ''}>{csvMsg('pending.valid_rows')}: {row.validRows}</span>
									{/if}
								</div>
							{/if}
							<div class="mt-1 font-mono text-[10px] text-muted-foreground/80">{row.jobId}</div>
							<div class="mt-3 flex flex-wrap gap-2">
								<Button
									size="sm"
									disabled={refreshing}
									onclick={async () => {
										const res = await fetchCsvImportStatus(row.jobId, row.profile);
										if (res.data && isWaitingConfirmationPayload(res.data)) {
											onResume(row, res.data as Record<string, unknown>);
											open = false;
										} else {
											removeCsvImportPending(row.jobId);
											rows = rows.filter((r) => r.jobId !== row.jobId);
											syncBadge();
										}
									}}
								>
									{csvMsg('pending.resume')}
								</Button>
								<Button size="sm" variant="ghost" onclick={() => removeLocal(row.jobId)}>{csvMsg('pending.remove')}</Button>
							</div>
						</li>
					{/each}
				</ul>
			{/if}
		</div>
	</Sheet.Content>
</Sheet.Root>
