<script lang="ts">
	import { onMount } from 'svelte';
	import { renderMarkdown, initDOMPurify } from '$lib/utils/markdown.js';
	import { formatDistanceToNow } from 'date-fns';
	import { api } from '$lib/utils/api.js';

	type Comment = {
		id: string;
		content: string;
		createdAt: string;
		updatedAt: string;
		userId: string;
		user: { id: string; name: string; avatarUrl: string | null };
	};

	type Props = {
		cardId: string;
		boardId: string;
		columnId: string | undefined;
		comments: Comment[];
		currentUserId: string;
		canEdit: boolean;
	};

	let { cardId, boardId, columnId, comments = [], currentUserId, canEdit }: Props = $props();

	let localComments = $state<Comment[]>(comments);
	let newContent = $state('');
	let submitting = $state(false);
	let editingId = $state<string | null>(null);
	let editContent = $state('');
	let ready = $state(false);

	onMount(async () => {
		await initDOMPurify();
		ready = true;
	});

	$effect(() => {
		localComments = comments;
	});

	const basePath = $derived(`/api/boards/${boardId}/columns/${columnId}/cards/${cardId}/comments`);

	async function addComment() {
		if (!newContent.trim()) return;
		submitting = true;
		const { ok, data } = await api(basePath, {
			method: 'POST',
			body: JSON.stringify({ content: newContent.trim() })
		});
		if (ok) {
			localComments = [data.comment, ...localComments];
			newContent = '';
		}
		submitting = false;
	}

	async function updateComment(commentId: string) {
		if (!editContent.trim()) return;
		const { ok, data } = await api(`${basePath}/${commentId}`, {
			method: 'PATCH',
			body: JSON.stringify({ content: editContent.trim() })
		});
		if (ok) {
			localComments = localComments.map((c) => (c.id === commentId ? data.comment : c));
			editingId = null;
		}
	}

	async function deleteComment(commentId: string) {
		const { ok } = await api(`${basePath}/${commentId}`, { method: 'DELETE' });
		if (ok) {
			localComments = localComments.filter((c) => c.id !== commentId);
		}
	}

	function startEdit(comment: Comment) {
		editingId = comment.id;
		editContent = comment.content;
	}
</script>

<div>
	<h3 class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase mb-2">Comments</h3>

	<!-- Add comment -->
	{#if canEdit}
		<div class="mb-4">
			<textarea
				bind:value={newContent}
				rows="3"
				placeholder="Write a comment... (Markdown supported)"
				class="w-full rounded-lg border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 p-3 text-sm resize-y focus:border-[var(--color-primary)] focus:outline-none focus:ring-1 focus:ring-[var(--color-primary)]"
			></textarea>
			<div class="flex justify-end mt-1">
				<button
					onclick={addComment}
					disabled={submitting || !newContent.trim()}
					class="rounded bg-[var(--color-primary)] px-3 py-1.5 text-sm text-white hover:bg-[var(--color-primary-hover)] transition disabled:opacity-50"
				>
					{submitting ? 'Posting...' : 'Comment'}
				</button>
			</div>
		</div>
	{/if}

	<!-- Comment list -->
	<div class="space-y-3">
		{#each localComments as comment}
			<div class="flex gap-2">
				<div class="w-7 h-7 rounded-full bg-[var(--color-primary)] text-white text-xs flex items-center justify-center flex-shrink-0 mt-0.5">
					{comment.user.name[0].toUpperCase()}
				</div>
				<div class="flex-1 min-w-0">
					<div class="flex items-center gap-2 mb-0.5">
						<span class="text-sm font-medium text-gray-800 dark:text-gray-200">{comment.user.name}</span>
						<span class="text-xs text-gray-400 dark:text-gray-500">
							{formatDistanceToNow(new Date(comment.createdAt), { addSuffix: true })}
						</span>
					</div>
					{#if editingId === comment.id}
						<div>
							<textarea
								bind:value={editContent}
								rows="3"
								class="w-full rounded border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 p-2 text-sm resize-y focus:border-[var(--color-primary)] focus:outline-none"
							></textarea>
							<div class="flex gap-2 mt-1">
								<button
									onclick={() => updateComment(comment.id)}
									class="rounded bg-[var(--color-primary)] px-2 py-1 text-xs text-white"
								>
									Save
								</button>
								<button
									onclick={() => (editingId = null)}
									class="text-xs text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300"
								>
									Cancel
								</button>
							</div>
						</div>
					{:else}
						<div class="prose text-sm text-gray-700 dark:text-gray-300">
							{#if ready}
								{@html renderMarkdown(comment.content)}
							{:else}
								<p class="whitespace-pre-wrap">{comment.content}</p>
							{/if}
						</div>
						<div class="flex gap-2 mt-1">
							{#if comment.userId === currentUserId}
								<button
									onclick={() => startEdit(comment)}
									class="text-xs text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300"
								>
									Edit
								</button>
							{/if}
							{#if comment.userId === currentUserId || canEdit}
								<button
									onclick={() => deleteComment(comment.id)}
									class="text-xs text-gray-400 dark:text-gray-500 hover:text-red-500"
								>
									Delete
								</button>
							{/if}
						</div>
					{/if}
				</div>
			</div>
		{/each}
	</div>

	{#if localComments.length === 0}
		<p class="text-xs text-gray-400 dark:text-gray-500 italic">No comments yet</p>
	{/if}
</div>
