<script lang="ts" module>
	import type { NovelsQuery, NovelStatus } from '$lib/graphql/__generated__/graphql';

	export type NovelNode = NonNullable<NonNullable<NovelsQuery['novels']>['edges']>[number]['node'];

	export interface NovelCardProps {
		novel: NovelNode;
	}

	const statusColors: Record<NovelStatus, string> = {
		IN_PROGRESS: 'bg-green-500 text-white',
		COMPLETED: 'bg-blue-500 text-white',
		HIATUS: 'bg-amber-500 text-white',
		ABANDONED: 'bg-gray-500 text-white',
		UNKNOWN: 'bg-gray-500 text-white'
	};

	const statusLabels: Record<NovelStatus, string> = {
		IN_PROGRESS: 'Ongoing',
		COMPLETED: 'Complete',
		HIATUS: 'Hiatus',
		ABANDONED: 'Dropped',
		UNKNOWN: 'Unknown'
	};
</script>

<script lang="ts">
	import { Card, CardContent, CardHeader, CardTitle } from '$lib/components/ui/card';
	import { Badge } from '$lib/components/ui/badge';
	import {
		Tooltip,
		TooltipTrigger,
		TooltipContent,
		TooltipProvider
	} from '$lib/components/ui/tooltip';
	import { formatRelativeTime, formatAbsoluteTime } from '$lib/utils/time';
	import { sanitizeHtml } from '$lib/utils/sanitize';

	let { novel }: NovelCardProps = $props();

	const title = $derived(novel.name || 'Untitled');
	const descriptionRaw = $derived(novel.description || 'No description available.');
	const descriptionHtml = $derived(sanitizeHtml(descriptionRaw));
	const coverSrc = $derived(novel.coverImage?.newPath ?? novel.coverImage?.originalPath);

	const latestChapter = $derived(
		novel.chapters?.slice().sort((a, b) => b.order - a.order)[0] ?? null
	);
	const chapterDisplay = $derived(latestChapter ? `Ch. ${latestChapter.order}` : null);

	const lastUpdated = $derived(novel.lastUpdatedTime ? new Date(novel.lastUpdatedTime) : null);
	const relativeTime = $derived(lastUpdated ? formatRelativeTime(lastUpdated) : null);
	const absoluteTime = $derived(lastUpdated ? formatAbsoluteTime(lastUpdated) : null);

	const status = $derived(novel.rawStatus ?? 'UNKNOWN');
	const statusColor = $derived(statusColors[status]);
	const statusLabel = $derived(statusLabels[status]);
</script>

<a
	href="/novels/{novel.id}"
	class="block focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-lg"
>
	<Card class="overflow-hidden border shadow-sm transition-shadow hover:shadow-md h-full pt-0 gap-0">
		<div class="relative">
			{#if coverSrc}
				<div class="aspect-[3/4] w-full overflow-hidden bg-muted/50">
					<img src={coverSrc} alt={title} class="h-full w-full object-cover" loading="lazy" />
				</div>
			{:else}
				<div class="aspect-[3/4] w-full bg-muted/50"></div>
			{/if}
			<Badge
				class="absolute top-2 right-2 {statusColor} shadow-sm"
				aria-label="Status: {statusLabel}"
			>
				{statusLabel}
			</Badge>
		</div>
		<CardHeader class="space-y-2 pt-4">
			<CardTitle class="line-clamp-2 text-lg leading-tight" title={title}>
				{title}
			</CardTitle>
		</CardHeader>
		<CardContent class="pt-0 pb-4 space-y-3">
			<div class="line-clamp-3 text-sm text-muted-foreground" title={descriptionRaw}>
				{@html descriptionHtml}
			</div>
			{#if chapterDisplay || relativeTime}
				<div class="flex items-center gap-1 text-xs text-muted-foreground/80">
					{#if chapterDisplay}
						<span>{chapterDisplay}</span>
					{/if}
					{#if chapterDisplay && relativeTime}
						<span aria-hidden="true">·</span>
					{/if}
					{#if relativeTime && absoluteTime}
						<TooltipProvider>
							<Tooltip>
								<TooltipTrigger class="cursor-default hover:text-foreground transition-colors">
									<time datetime={lastUpdated?.toISOString()}>{relativeTime}</time>
								</TooltipTrigger>
								<TooltipContent>
									{absoluteTime}
								</TooltipContent>
							</Tooltip>
						</TooltipProvider>
					{/if}
				</div>
			{/if}
		</CardContent>
	</Card>
</a>
