<script lang="ts">
	import * as Card from '$lib/components/ui/card/index.js';
	import { Badge } from '$lib/components/ui/badge/index.js';
	import { Button } from '$lib/components/ui/button/index.js';
	import { Pin } from '@lucide/svelte';
	import NoteActionMenu from './NoteActionMenu.svelte';
	import { Carta, Markdown } from 'carta-md';
	import DOMPurify from 'isomorphic-dompurify';
	import { getNoteService } from '$lib/context/notes.svelte';

	let { noteId, view = 'grid', onclick }: { noteId: string; view?: 'grid' | 'list'; onclick?: () => void } = $props();

	const noteService = getNoteService();
	const note = $derived(noteService.getNoteById(noteId));

	const carta = new Carta({
		sanitizer: DOMPurify.sanitize,
		theme: { light: 'github-light', dark: 'github-dark' }
	});

	function handleUnpin(e: Event) {
		e.stopPropagation();
		if (note) noteService.updateNote(note.id, { pinned: false });
	}

	function getPreview(content: string) {
		const lines = view === 'grid' ? 3 : 2;
		const preview = content.split('\n').slice(0, lines).join('\n');
		return preview.length > 150 ? preview.substring(0, 150) + '...' : preview;
	}

	function getRelativeTime(date: Date) {
		const diff = Date.now() - date.getTime();
		const minutes = Math.floor(diff / 60000);
		const hours = Math.floor(minutes / 60);
		const days = Math.floor(hours / 24);
		if (days > 0) return `${days}d ago`;
		if (hours > 0) return `${hours}h ago`;
		if (minutes > 0) return `${minutes}m ago`;
		return 'Just now';
	}
</script>

{#if note}
	<Card.Root
		class="cursor-pointer transition-all hover:shadow-md gap-2 {view === 'list' ? 'flex flex-row' : ''}"
		role="button"
		tabindex={0}
		{onclick}
		onkeydown={(e) => (e.key === 'Enter' || e.key === ' ') && (e.preventDefault(), onclick?.())}
	>
		<div class="flex items-center justify-between gap-2 pl-6 pr-2">
			<h3 class="font-semibold text-base line-clamp-1 flex-1 min-w-0">
				{note.title || note.content.split('\n')[0] || 'Untitled'}
			</h3>
			<div class="flex items-center gap-1 shrink-0">
				{#if note.pinned}
					<Button variant="ghost" size="icon-sm" onclick={handleUnpin} title="Unpin note" class="group">
						<Pin class="h-4 w-4 text-primary transition-all group-hover:rotate-45 group-hover:text-muted-foreground" />
						<span class="sr-only">Unpin note</span>
					</Button>
				{/if}
				<NoteActionMenu {note} />
			</div>
		</div>

		<Card.Content class="flex-1">
			{#if note.content}
				<div class="note-preview text-sm text-muted-foreground {view === 'grid' ? 'line-clamp-3' : 'line-clamp-2'} overflow-hidden">
					{#key note.content}
						<Markdown {carta} value={getPreview(note.content)} />
					{/key}
				</div>
			{/if}

			{#if note.tags.size > 0}
				{@const tags = Array.from(note.tags)}
				<div class="flex flex-wrap gap-1 mt-3">
					{#each tags.slice(0, 3) as tag (tag)}
						<Badge variant="outline" class="text-xs">{tag}</Badge>
					{/each}
					{#if tags.length > 3}
						<Badge variant="outline" class="text-xs">+{tags.length - 3}</Badge>
					{/if}
				</div>
			{/if}
		</Card.Content>

		<Card.Footer class="justify-end">
			<span class="text-xs text-muted-foreground">{getRelativeTime(note.updatedAt)}</span>
		</Card.Footer>
	</Card.Root>
{/if}

<style>
	.note-preview :global(*) {
		margin: 0;
	}
</style>
