<script lang="ts">
	import * as Empty from '$lib/components/ui/empty/index.js';
	import { Button } from '$lib/components/ui/button/index.js';
	import { Spinner } from '$lib/components/ui/spinner/index.js';
	import { ScrollArea } from '$lib/components/ui/scroll-area/index';
	import { SearchX, FolderX, FunnelX, Upload } from '@lucide/svelte';

	import BookGrid from './book-grid.svelte';

	import * as Sidebar from '$lib/components/ui/sidebar/index.js';
	import FilterSidebar from '$lib/components/view/filter-sidebar.svelte';
	import FilterButton from './filter-button.svelte';
	import SortButton from './sort-button.svelte';
	import ViewToggle from './view-toggle.svelte';
	import BookTable from './book-table.svelte';
	import BatchOperationsToolbar from './batch-operations-toolbar.svelte';
	import { getBookCollectionState } from '$lib/state/bookCollection.svelte';
	import { getBookSelectionState } from '$lib/state/bookSelection.svelte';
	import { getBookOperationsState } from '$lib/state/bookOperations.svelte';

	const selectionState = getBookSelectionState();
	const bookCollection = getBookCollectionState();
	const bookOps = getBookOperationsState();

	let view = $state('grid');
	let sentinel = $state<HTMLElement>();
	let scrollContainer = $state<HTMLElement | null>(null);

	$effect(() => {
		if (!sentinel || !bookCollection.moreBooks) return;
		const observer = new IntersectionObserver(
			async (entries) => {
				if (entries[0].isIntersecting && !bookCollection.loading) {
					await bookCollection.loadMoreBooks();
				}
			},
			{ 
				root: scrollContainer,
				rootMargin: '0px 0px 200px 0px' 
			}
		);

		observer.observe(sentinel);

		return () => {
			observer.disconnect();
		};
	});

	// TODO: Set initial sidebar state to the previous state (saved in cookies)
	// 		If there is is no previous state, it is opened if there are active filters o.w closed
	let initialFilterSidebarOpen = bookCollection.hasActiveFilters;
</script>

<div class="flex h-full w-full flex-col">
	<!-- Main Content Area -->
	<div class="flex h-0 w-full flex-1">
		<!-- Sidebar Layout -->
		<Sidebar.Provider
			contextKey="FILTER_SIDEBAR"
			open={initialFilterSidebarOpen}
			class="flex h-full w-full"
		>
			<!-- Sidebar Area -->
			<Sidebar.Inset class="flex min-w-0 flex-1">
				<div class="top-0 z-1 mb-4 flex h-12 w-full rounded-lg border bg-sidebar px-5">
					<div class="flex w-full items-center py-2">
						{#if !selectionState.selectionModeActive}
							<ViewToggle bind:view />

							<div class="ml-auto">
								<SortButton />
								<FilterButton />
							</div>
						{:else}
							<p class="ml-2 font-medium">
								Selected {selectionState.numSelected()} book{selectionState.numSelected() > 1
									? 's'
									: ''}
							</p>

							<div class="ml-auto">
								<BatchOperationsToolbar />
							</div>
						{/if}
					</div>
				</div>

				{#if bookCollection.loading && bookCollection.books.length === 0}
					<div class="mb-[25vh] flex h-full w-full items-center justify-center">
						<Spinner />
					</div>
				{:else if bookCollection.books.length > 0}
					<ScrollArea bind:viewportRef={scrollContainer} orientation="both" class=" h-[calc(100vh-12vh)] w-full pr-5 pl-5">
						{#if view === 'grid'}
							<BookGrid books={bookCollection.books} />
						{:else}
							<BookTable books={bookCollection.books} />
						{/if}

						{#if bookCollection.moreBooks}
							<div bind:this={sentinel}>
								{#if bookCollection.loading}
									<Spinner />
								{/if}
							</div>
						{/if}
					</ScrollArea>
				{:else if bookCollection.books.length === 0 && !bookCollection.hasActiveFilters}
					<!-- Show a CTA to upload books if the library is empty -->
					<Empty.Root class="mb-[20vh]">
						<Empty.Header>
							<Empty.Media variant="icon">
								<FolderX />
							</Empty.Media>
							<Empty.Title>Library Empty</Empty.Title>
							<Empty.Description>
								This library doesn't have any books yet. Get started by uploading your first books.
							</Empty.Description>
						</Empty.Header>
						<Empty.Content>
							<Button onclick={async () => (bookOps.uploadDialogOpen = true)}>
								<Upload />
								Upload Books
							</Button>
						</Empty.Content>
					</Empty.Root>
				{:else if bookCollection.books.length === 0 && bookCollection.hasActiveFilters}
					<!-- Show no results if the given filters result in no books -->
					<Empty.Root class="mb-[20vh]">
						<Empty.Header>
							<Empty.Media variant="icon">
								<SearchX />
							</Empty.Media>
							<Empty.Title>No Results</Empty.Title>
							<Empty.Description>
								No books exist with the applied filters. Adjust your filters.
							</Empty.Description>
						</Empty.Header>
						<Empty.Content>
							<Button variant="outline" onclick={() => bookCollection.clearFilters()}>
								<FunnelX />
								Clear Filters
							</Button>
						</Empty.Content>
					</Empty.Root>
				{/if}
			</Sidebar.Inset>

			<!-- Filter Sidebar (right-side) -->
			<FilterSidebar class="m-2 pb-5 h-full pt-20" />
		</Sidebar.Provider>
	</div>
</div>
