<script lang="ts">
	import { onMount } from 'svelte';
	import {
		AuditLogAPI,
		type AuditLog,
		type AuditLogParams
	} from '$lib/api/dashboard/a76/audit_log';
	import * as Card from '$lib/components/ui/card';
	import { Button } from '$lib/components/ui/button';
	import { Input } from '$lib/components/ui/input';
	import { Label } from '$lib/components/ui/label';
	import * as Table from '$lib/components/ui/table';
	import {
		RefreshCw,
		Search,
		ChevronLeft,
		ChevronRight,
		ChevronsLeft,
		ChevronsRight
	} from 'lucide-svelte';

	// State
	let logs: AuditLog[] = []; // $state([]) in runes mode, but using let for now as per file style
	let total: number = 0;
	let page: number = 1;
	let pageSize: number = 50;
	let loading: boolean = false;
	let error: string | null = null;
	let totalPages: number = 1;

	// Filters
	let search: string = '';
	let usernameFilter: string = '';
	let procedureFilter: string = '';
	let dateFrom: string = '';
	let dateTo: string = '';

	let procedures: string[] = [];

	// Selected Log for detail modal (if needed, or navigate)
	let selectedLog: AuditLog | null = null;

	// Infinite Scroll State
	let hasMore: boolean = true;
	let sentinel: HTMLElement;

	async function loadLogs() {
		if (loading) return;
		loading = true;
		error = null;
		try {
			const params: AuditLogParams = {
				page,
				page_size: pageSize,
				search: search || undefined,
				username: usernameFilter || undefined,
				procedure: procedureFilter || undefined,
				date_from: dateFrom || undefined,
				date_to: dateTo || undefined
			};

			const response = await AuditLogAPI.getLogs(params);

			if (page === 1) {
				logs = response.data;
			} else {
				logs = [...logs, ...response.data];
			}

			total = response.total;
			hasMore = logs.length < total;
		} catch (e: any) {
			error = e.message;
		} finally {
			loading = false;
		}
	}

	async function loadProcedures() {
		try {
			procedures = await AuditLogAPI.getProcedures();
		} catch (e) {
			console.error(e);
		}
	}

	// Debounce timer
	let timer: ReturnType<typeof setTimeout>;

	function handleFilterChange() {
		page = 1;
		hasMore = true;
		// Reset logs immediately to avoid confusion (optional, but good for UX)
		logs = [];
		loadLogs();
	}

	function handleSearchInput() {
		clearTimeout(timer);
		timer = setTimeout(() => {
			page = 1;
			hasMore = true;
			logs = [];
			loadLogs();
		}, 300);
	}

	function clearFilters() {
		search = '';
		usernameFilter = '';
		procedureFilter = '';
		dateFrom = '';
		dateTo = '';
		handleFilterChange();
	}

	function formatDate(dateStr: string, timestamp?: string): string {
		if (timestamp) {
			return new Date(timestamp).toLocaleDateString();
		}
		if (!dateStr) return '';
		const [y, m, d] = dateStr.split('-');
		return `${d}/${m}/${y}`;
	}

	function formatTime(timeStr: string, timestamp?: string): string {
		if (timestamp) {
			return new Date(timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
		}
		if (!timeStr) return '';
		try {
			const [h, m] = timeStr.split(':');
			let hour = parseInt(h);
			const ampm = hour >= 12 ? 'PM' : 'AM';
			hour = hour % 12;
			hour = hour ? hour : 12;
			return `${hour.toString().padStart(2, '0')}:${m} ${ampm}`;
		} catch {
			return timeStr;
		}
	}

	onMount(() => {
		loadProcedures();
		loadLogs();

		// Intersection Observer for Infinite Scroll
		const observer = new IntersectionObserver(
			(entries) => {
				if (entries[0].isIntersecting && hasMore && !loading) {
					page++;
					loadLogs();
				}
			},
			{ rootMargin: '100px' }
		);

		if (sentinel) {
			observer.observe(sentinel);
		}

		return () => {
			observer.disconnect();
		};
	});
	import * as m from '$lib/paraglide/messages.js';
</script>

<div class="flex h-[calc(100vh-85px)] flex-col space-y-4 overflow-hidden">
	<div class="flex flex-none items-center justify-between">
		<div>
			<h1 class="text-3xl font-bold tracking-tight">{m['sidebar.audit_logs_title']()}</h1>
			<p class="text-muted-foreground">{m['sidebar.audit_logs_description']()}</p>
		</div>
		<div class="flex gap-2">
			<Button
				variant="outline"
				onclick={() => {
					page = 1;
					hasMore = true;
					logs = [];
					loadLogs();
				}}
				disabled={loading}
			>
				<RefreshCw class="mr-2 h-4 w-4 {loading ? 'animate-spin' : ''}" />
				Actualizar
			</Button>
		</div>
	</div>

	<!-- Filters -->
	<div class="flex-none">
		<Card.Root>
			<Card.Header class="py-3">
				<Card.Title class="text-lg">Filtros</Card.Title>
			</Card.Header>
			<Card.Content>
				<div class="grid grid-cols-1 gap-4 md:grid-cols-3 lg:grid-cols-5">
					<div class="space-y-1">
						<Label for="search" class="text-xs">Búsqueda General</Label>
						<div class="relative">
							<Search class="absolute top-2.5 left-2 h-4 w-4 text-muted-foreground" />
							<Input
								id="search"
								placeholder="Ref, Mov, Usuario..."
								class="h-9 pl-8"
								bind:value={search}
								oninput={handleSearchInput}
							/>
						</div>
					</div>

					<div class="space-y-1">
						<Label for="username" class="text-xs">Usuario</Label>
						<Input
							id="username"
							placeholder="Filtrar por usuario"
							class="h-9"
							bind:value={usernameFilter}
							oninput={handleSearchInput}
						/>
					</div>

					<div class="space-y-1">
						<Label for="procedure" class="text-xs">Procedimiento</Label>
						<select
							id="procedure"
							bind:value={procedureFilter}
							onchange={handleFilterChange}
							class="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
						>
							<option value="">Todos</option>
							{#each procedures as proc}
								<option value={proc}>{proc}</option>
							{/each}
						</select>
					</div>

					<div class="space-y-1">
						<Label for="dateFrom" class="text-xs">Desde</Label>
						<Input
							id="dateFrom"
							type="date"
							class="h-9"
							bind:value={dateFrom}
							onchange={handleFilterChange}
						/>
					</div>

					<div class="space-y-1">
						<Label for="dateTo" class="text-xs">Hasta</Label>
						<Input
							id="dateTo"
							type="date"
							class="h-9"
							bind:value={dateTo}
							onchange={handleFilterChange}
						/>
					</div>
				</div>
				<div class="mt-2 flex justify-end">
					<Button variant="ghost" onclick={clearFilters} size="sm" class="h-8 text-xs font-normal"
						>Limpiar Filtros</Button
					>
				</div>
			</Card.Content>
		</Card.Root>
	</div>

	<!-- Table -->
	<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 class="text-lg">Registros</Card.Title>
					<Card.Description class="text-xs">Total: {total} registros encontrados</Card.Description>
				</div>
			</div>
		</Card.Header>
		<Card.Content class="flex min-h-0 flex-1 flex-col p-0 px-6 pb-6">
			{#if error}
				<div class="rounded-md bg-red-50 p-4 text-center text-red-500">
					Error al cargar datos: {error}
				</div>
			{:else}
				<div class="relative min-h-0 flex-1 overflow-y-auto rounded-md border bg-card shadow-inner">
					<Table.Root>
						<Table.Header class="sticky top-0 z-10 bg-background/95 shadow-sm backdrop-blur-sm">
							<Table.Row>
								<Table.Head class="w-[80px]">ID</Table.Head>
								<Table.Head class="w-[180px]">Referencia</Table.Head>
								<Table.Head>Procedimiento</Table.Head>
								<Table.Head>Movimiento</Table.Head>
								<Table.Head class="w-[150px]">Usuario</Table.Head>
								<Table.Head class="w-[120px]">Fecha</Table.Head>
								<Table.Head class="w-[120px]">Hora</Table.Head>
							</Table.Row>
						</Table.Header>
						<Table.Body>
							{#if loading && logs.length === 0}
								<Table.Row>
									<Table.Cell colspan={7} class="h-24 text-center text-muted-foreground italic"
										>Cargando...</Table.Cell
									>
								</Table.Row>
							{:else if logs.length === 0}
								<Table.Row>
									<Table.Cell colspan={7} class="h-24 text-center text-muted-foreground"
										>No se encontraron registros</Table.Cell
									>
								</Table.Row>
							{:else}
								{#each logs as log}
									<Table.Row class="transition-colors hover:bg-muted/50">
										<Table.Cell class="text-xs font-medium text-muted-foreground"
											>{log.spec_id}</Table.Cell
										>
										<Table.Cell class="text-sm font-bold text-blue-600 dark:text-blue-400"
											>{log.reference}</Table.Cell
										>
										<Table.Cell class="text-sm">{log.procedure}</Table.Cell>
										<Table.Cell class="text-sm">{log.movement}</Table.Cell>
										<Table.Cell class="text-sm">{log.username}</Table.Cell>
										<Table.Cell class="text-sm">{formatDate(log.date, log.timestamp)}</Table.Cell>
										<Table.Cell class="text-sm">{formatTime(log.time, log.timestamp)}</Table.Cell>
									</Table.Row>
								{/each}
							{/if}
						</Table.Body>
					</Table.Root>

					<!-- Infinite Scroll Sentinel (Inside the scrollable container) -->
					<div bind:this={sentinel} class="flex h-12 w-full items-center justify-center p-4">
						{#if loading && logs.length > 0}
							<div class="flex items-center gap-2">
								<RefreshCw class="h-4 w-4 animate-spin text-primary" />
								<span class="text-sm text-muted-foreground">Cargando más registros...</span>
							</div>
						{/if}
					</div>
				</div>
			{/if}
		</Card.Content>
	</Card.Root>
</div>
