<script lang="ts">
	import { onMount } from 'svelte';
	import { client } from '$lib/graphql/client';
	import { NovelsDocument, type NovelsQuery } from '$lib/graphql/__generated__/graphql';
	import NovelCard from './NovelCard.svelte';
	import { Button } from '$lib/components/ui/button';
	import { Card, CardContent, CardHeader, CardTitle } from '$lib/components/ui/card';

	const PAGE_SIZE = 12;

	type NovelEdge = NonNullable<NovelsQuery['novels']>['edges'][number];

	let edges: NovelEdge[] = $state([]);
	let pageInfo: NonNullable<NovelsQuery['novels']>['pageInfo'] | null = $state(null);
	let fetching = $state(false);
	let error: string | null = $state(null);
	let initialLoad = $state(true);

	const hasNextPage = $derived(pageInfo?.hasNextPage ?? false);
	const novels = $derived(edges.map((edge) => edge.node).filter(Boolean));

	async function fetchNovels(after: string | null = null) {
		fetching = true;
		error = null;

		try {
			const result = await client.query(NovelsDocument, { first: PAGE_SIZE, after }).toPromise();

			if (result.error) {
				error = result.error.message;
				return;
			}

			if (result.data?.novels) {
				if (after) {
					// Append for pagination
					edges = [...edges, ...result.data.novels.edges];
				} else {
					// Initial load
					edges = result.data.novels.edges;
				}
				pageInfo = result.data.novels.pageInfo;
			}
		} catch (e) {
			error = e instanceof Error ? e.message : 'Unknown error';
		} finally {
			fetching = false;
			initialLoad = false;
		}
	}

	function loadMore() {
		if (pageInfo?.endCursor) {
			fetchNovels(pageInfo.endCursor);
		}
	}

	onMount(() => {
		fetchNovels();
	});
</script>

<div class="space-y-4">
	<Card class="shadow-md shadow-primary/10">
		<CardHeader>
			<CardTitle>Latest Novels</CardTitle>
			<p class="text-sm text-muted-foreground">Novels that have recently been updated.</p>
		</CardHeader>
	</Card>

	{#if fetching && initialLoad}
		<Card>
			<CardContent>
				<div class="flex items-center justify-center py-8">
					<div
						class="h-10 w-10 animate-spin rounded-full border-2 border-primary border-t-transparent"
						aria-label="Loading novels"
					></div>
				</div>
			</CardContent>
		</Card>
	{/if}

	{#if error}
		<Card class="border-destructive/40 bg-destructive/5">
			<CardContent>
				<p class="py-4 text-sm text-destructive">Could not load novels: {error}</p>
			</CardContent>
		</Card>
	{/if}

	{#if !fetching && novels.length === 0 && !error && !initialLoad}
		<Card>
			<CardContent>
				<p class="py-4 text-sm text-muted-foreground">
					No novels found yet. Try adding content to the gateway.
				</p>
			</CardContent>
		</Card>
	{/if}

	{#if novels.length > 0}
		<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
			{#each novels as novel (novel.id)}
				<NovelCard {novel} />
			{/each}
		</div>
	{/if}

	{#if hasNextPage}
		<div class="flex justify-center">
			<Button onclick={loadMore} variant="outline" disabled={fetching} class="min-w-[160px]">
				{fetching ? 'Loading...' : 'Load more'}
			</Button>
		</div>
	{/if}
</div>
