<script lang="ts">
	import { getComments, postComment, deleteComment } from '$lib/api/actions';
	import { session, isModOrAdmin } from '$lib/stores/session';
	import { flash } from '$lib/stores/flash';
	import { timeAgo, formatDate } from '$lib/utils/timeago';
	import { onSSE } from '$lib/stores/sse';
	import { onDestroy } from 'svelte';
	import type { Comment } from '$lib/types/comment';

	interface Props {
		itemId: number;
	}
	let { itemId }: Props = $props();

	// ── State ─────────────────────────────────────────────────────────────────
	let comments  = $state<Comment[]>([]);
	let loading   = $state(true);
	let error     = $state('');
	let text      = $state('');
	let replyTo   = $state<Comment | null>(null);
	let submitting = $state(false);

	// ── Load ──────────────────────────────────────────────────────────────────
	async function load() {
		loading = true;
		error = '';
		try {
			const data = await getComments(itemId);
			comments = data.comments ?? [];
		} catch {
			error = 'Failed to load comments.';
		} finally {
			loading = false;
		}
	}

	// Run on mount and when itemId changes
	$effect(() => { load(); });

	// ── Live updates via SSE ──────────────────────────────────────────────────
	const unsubSSE = onSSE((event) => {
		if (event.type !== 'comments') return;
		const d = event.data as { item_id: number; type?: string };
		if (d.item_id !== itemId) return;
		// Reload the full comment list on any comment activity for this item
		load();
	});
	onDestroy(unsubSSE);

	// ── Post comment ──────────────────────────────────────────────────────────
	async function submit(e: Event) {
		e.preventDefault();
		if (!text.trim()) return;
		submitting = true;
		try {
			const res = await postComment({
				itemId,
				content: text.trim(),
				replyTo: replyTo?.id ?? null
			});
			if (res.success) {
				text = '';
				replyTo = null;
				await load();
				flash('Comment posted', 'success');
			} else {
				flash(res.message ?? res.msg ?? 'Failed to post', 'error');
			}
		} catch {
			flash('Network error', 'error');
		} finally {
			submitting = false;
		}
	}

	// ── Delete comment ────────────────────────────────────────────────────────
	async function handleDelete(comment: Comment) {
		if (!confirm('Delete this comment?')) return;
		try {
			const res = await deleteComment(comment.id);
			if (res.success) {
				await load();
				flash('Deleted', 'success');
			} else {
				flash(res.msg ?? 'Failed to delete', 'error');
			}
		} catch {
			flash('Network error', 'error');
		}
	}

	function canDelete(comment: Comment) {
		return $session && ($isModOrAdmin || $session.user === comment.username);
	}

	function avatarSrc(comment: Comment): string {
		if (comment.avatar_file) return `/a/${comment.avatar_file}`;
		if (comment.avatar)      return `/t/${comment.avatar}.webp`;
		return '/a/default.png';
	}
</script>

<section class="flex flex-col gap-3">
	<!-- Header -->
	<div class="flex items-center justify-between">
		<span class="text-xs font-semibold uppercase tracking-wider opacity-50">
			Comments {#if comments.length > 0}<span class="opacity-60">({comments.length})</span>{/if}
		</span>
		<button onclick={load} class="btn btn-xs btn-ghost opacity-50 hover:opacity-100" aria-label="Refresh">
			<i class="fa-solid fa-rotate-right text-xs" aria-hidden="true"></i>
		</button>
	</div>

	<!-- Comment form -->
	{#if $session}
		<form onsubmit={submit} class="flex flex-col gap-2">
			{#if replyTo}
				<div class="flex items-center gap-2 text-xs bg-base-300 rounded px-2 py-1">
					<i class="fa-solid fa-reply opacity-50" aria-hidden="true"></i>
					<span class="opacity-70 truncate flex-1">Replying to {replyTo.display_name || replyTo.username}</span>
					<button type="button" onclick={() => replyTo = null} class="opacity-50 hover:opacity-100">✕</button>
				</div>
			{/if}
			<div class="flex gap-2">
				<textarea
					bind:value={text}
					placeholder="Write a comment…"
					rows="2"
					class="textarea textarea-bordered flex-1 text-sm resize-none min-h-[3rem]"
					disabled={submitting}
					onkeydown={(e) => { if (e.key === 'Enter' && e.ctrlKey) submit(e); }}
				></textarea>
				<button
					type="submit"
					class="btn btn-primary btn-sm self-end"
					disabled={submitting || !text.trim()}
				>
					{#if submitting}
						<span class="loading loading-spinner loading-xs"></span>
					{:else}
						<i class="fa-solid fa-paper-plane" aria-hidden="true"></i>
					{/if}
				</button>
			</div>
			<p class="text-xs opacity-30">Ctrl+Enter to submit</p>
		</form>
	{:else}
		<p class="text-xs opacity-40">
			<a href="/login" class="link link-primary">Log in</a> to comment.
		</p>
	{/if}

	<!-- Comments list -->
	{#if loading}
		<div class="flex justify-center py-4">
			<span class="loading loading-dots loading-sm opacity-40"></span>
		</div>
	{:else if error}
		<p class="text-xs text-error opacity-70">{error}</p>
	{:else if comments.length === 0}
		<p class="text-xs opacity-30 text-center py-2">No comments yet.</p>
	{:else}
		<ul class="flex flex-col gap-2">
			{#each comments as comment (comment.id)}
				<li
					class="group flex gap-2 text-sm {comment.is_deleted ? 'opacity-40' : ''}"
					id="comment-{comment.id}"
				>
					<!-- Avatar -->
					<a href="/user/{comment.username?.toLowerCase()}" class="flex-shrink-0 mt-0.5">
						<div class="avatar">
							<div class="w-7 rounded-full border border-base-300">
								<img src={avatarSrc(comment)} alt={comment.username} loading="lazy" />
							</div>
						</div>
					</a>

					<!-- Body -->
					<div class="flex-1 min-w-0">
						<div class="flex items-baseline gap-1.5 flex-wrap">
							<a
								href="/user/{comment.username?.toLowerCase()}"
								class="font-semibold text-xs hover:text-primary transition-colors"
								style={comment.username_color ? `color: ${comment.username_color}` : ''}
							>
								{comment.display_name || comment.username}
							</a>
							<time
								datetime={comment.stamp_full}
								title={formatDate(comment.stamp_full)}
								class="text-xs opacity-40"
							>
								{comment.stamp}
							</time>
						</div>

						{#if comment.is_deleted}
							<p class="text-xs italic opacity-50">— deleted —</p>
						{:else}
							<!-- eslint-disable-next-line svelte/no-at-html-tags -->
							<div class="prose prose-sm max-w-none text-xs leading-relaxed break-words">
								{@html comment.content}
							</div>
						{/if}

						<!-- Actions -->
						{#if !comment.is_deleted}
							<div class="flex items-center gap-2 mt-1 opacity-0 group-hover:opacity-100 transition-opacity">
								{#if $session}
									<button
										onclick={() => { replyTo = comment; document.querySelector('textarea')?.focus(); }}
										class="btn btn-ghost btn-xs gap-1 text-xs"
									>
										<i class="fa-solid fa-reply text-[10px]" aria-hidden="true"></i> Reply
									</button>
								{/if}
								{#if canDelete(comment)}
									<button
										onclick={() => handleDelete(comment)}
										class="btn btn-ghost btn-xs text-error gap-1 text-xs"
									>
										<i class="fa-solid fa-xmark text-[10px]" aria-hidden="true"></i> Delete
									</button>
								{/if}
							</div>
						{/if}
					</div>
				</li>
			{/each}
		</ul>
	{/if}
</section>
