<script lang="ts">
	import { liveQuery } from 'dexie';
	import { db } from '$lib/db/schema';
	import { getOrCreateJournalTopic, createHistoryEntry, updateHistoryEntry, softDeleteHistoryEntry, createTopic, JOURNAL_TOPIC_ID } from '$lib/db/repositories';
	import { today } from '$lib/db/helpers';
	import { mention } from '$lib/actions/mention';
	import MarkdownEditor from './MarkdownEditor.svelte';
	import RenderedMarkdown from './RenderedMarkdown.svelte';
	import DateNavigator from './DateNavigator.svelte';
	import ConfirmDialog from './ConfirmDialog.svelte';
	import WiedervorlageSection from './WiedervorlageSection.svelte';

	interface Props {
		contextId: string;
	}
	let { contextId }: Props = $props();

	const isDailyLog = $derived(contextId === 'daily-log');

	// --- Daily-log journal mode ---
	let entryTitle = $state('');
	let entryText = $state('');
	let entryEditor: MarkdownEditor;
	let selectedDate = $state(today());
	let selectedLinkedContextId = $state('');
	let wiedervorlageChecked = $state(false);

	// All meeting contexts for the link dropdown
	const meetingContexts = liveQuery(() =>
		db.contexts
			.filter(c => !c.deletedAt && c.type === 'meeting' && c.id !== 'daily-log')
			.sortBy('sortOrder')
	);

	// All journal entries (daily-log mode)
	const journalEntries = liveQuery(async () => {
		if (!isDailyLog) return [];
		const topic = await db.topics.get(JOURNAL_TOPIC_ID);
		if (!topic) return [];
		return db.historyEntries
			.where('topicId').equals(JOURNAL_TOPIC_ID)
			.filter(h => !h.deletedAt)
			.toArray();
	});

	// Filter journal entries by selected date
	const filteredEntries = $derived(
		($journalEntries ?? [])
			.filter(e => e.date === selectedDate)
			.sort((a, b) => b.sortOrder - a.sortOrder)
	);

	// Context name lookup for linked entries
	const contextNameMap = $derived(() => {
		const map = new Map<string, string>();
		for (const ctx of $meetingContexts ?? []) {
			map.set(ctx.id, ctx.name);
		}
		return map;
	});

	async function handleAddEntry() {
		const title = entryTitle.trim();
		const body = entryText.trim();
		if (!title) return;

		if (selectedLinkedContextId) {
			const topic = await createTopic(selectedLinkedContextId, title);
			if (body) {
				await createHistoryEntry(topic.id, selectedDate, body);
			}
		} else {
			const text = body ? `${title}\n${body}` : title;
			await getOrCreateJournalTopic();
			await createHistoryEntry(JOURNAL_TOPIC_ID, selectedDate, text, null, wiedervorlageChecked);
		}

		entryTitle = '';
		entryText = '';
		entryEditor?.clear();
		selectedLinkedContextId = '';
		wiedervorlageChecked = false;
	}

	function handleTitleKeypress(e: KeyboardEvent) {
		if (e.key === 'Enter') handleAddEntry();
	}

	let confirmDeleteId = $state<string | null>(null);

	// --- Edit mode ---
	let editingId = $state<string | null>(null);
	let editTitle = $state('');
	let editBody = $state('');

	function startEdit(entry: { id: string; text: string }) {
		const lines = entry.text.split('\n');
		editingId = entry.id;
		editTitle = lines[0];
		editBody = lines.slice(1).join('\n').trim();
	}

	function cancelEdit() {
		editingId = null;
	}

	async function saveEdit() {
		if (!editingId || !editTitle.trim()) return;
		const text = editBody.trim() ? `${editTitle.trim()}\n${editBody.trim()}` : editTitle.trim();
		await updateHistoryEntry(editingId, text);
		editingId = null;
	}

	async function handleDelete(id: string) {
		confirmDeleteId = id;
	}

	async function confirmDelete() {
		if (confirmDeleteId) await softDeleteHistoryEntry(confirmDeleteId);
		confirmDeleteId = null;
	}

	function formatTime(isoString: string): string {
		try {
			return new Date(isoString).toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' });
		} catch {
			return '';
		}
	}

	// --- Meeting journal mode ---
	const meetingEntries = liveQuery(async () => {
		if (isDailyLog) return [];
		const topics = await db.topics
			.where('contextId').equals(contextId)
			.filter(t => !t.deletedAt)
			.toArray();
		const topicMap = new Map(topics.map(t => [t.id, t.title]));
		const history = await db.historyEntries
			.where('topicId').anyOf(topics.map(t => t.id))
			.filter(h => !h.deletedAt)
			.toArray();

		// Also fetch journal entries linked to this context
		const linked = await db.historyEntries
			.where('linkedContextId').equals(contextId)
			.filter(h => !h.deletedAt)
			.toArray();

		const all = [
			...history.map(h => ({ ...h, topicTitle: topicMap.get(h.topicId) ?? '', isLinked: false })),
			...linked.map(h => ({ ...h, topicTitle: 'Journal', isLinked: true }))
		];
		return all.sort((a, b) => b.date.localeCompare(a.date));
	});

	const meetingByDate = $derived(() => {
		const groups = new Map<string, typeof $meetingEntries>();
		for (const entry of $meetingEntries ?? []) {
			const existing = groups.get(entry.date) ?? [];
			existing.push(entry);
			groups.set(entry.date, existing);
		}
		return [...groups.entries()].sort(([a], [b]) => b.localeCompare(a));
	});
</script>

{#if isDailyLog}
	<!-- Daily-log: chronological entry log with date navigation -->
	<DateNavigator {selectedDate} onchange={(d) => selectedDate = d} />

	<div class="mb-8 flex flex-col gap-2.5 rounded-lg border border-border bg-sidebar p-4">
		<div class="flex items-center gap-2">
			<input
				type="text"
				class="flex-1 rounded border border-[#444] bg-bg px-2.5 py-2 font-mono text-white"
				placeholder="Titel / Was ist passiert?"
				bind:value={entryTitle}
				onkeypress={handleTitleKeypress}
				use:mention
			/>
			<select
				class="rounded border border-[#444] bg-bg px-2 py-2 text-sm text-white"
				bind:value={selectedLinkedContextId}
			>
				<option value="">— kein Jour-fix —</option>
				{#each $meetingContexts ?? [] as ctx}
					<option value={ctx.id}>{ctx.name}</option>
				{/each}
			</select>
		</div>
		<MarkdownEditor
			bind:this={entryEditor}
			placeholder="Details (optional)"
			minHeight="60px"
			onchange={(md) => entryText = md}
		/>
		<div class="flex items-center gap-4">
			<button
				class="rounded bg-accent px-4 py-2 font-bold text-white hover:brightness-110"
				onclick={handleAddEntry}
			>
				+ {selectedLinkedContextId ? 'Thema hinzufügen' : 'Notiz hinzufügen'}
			</button>
			{#if !selectedLinkedContextId}
				<label class="flex cursor-pointer items-center gap-1.5 text-sm text-muted">
					<input type="checkbox" bind:checked={wiedervorlageChecked} class="accent-amber-500" />
					Wiedervorlage
				</label>
			{/if}
		</div>
	</div>

	<WiedervorlageSection date={selectedDate} />

	{#if filteredEntries.length > 0}
		<div class="mb-8 border-l-2 border-[#555] pl-5">
			<div class="mb-4 text-xl font-bold text-accent">{selectedDate}</div>
			{#each filteredEntries as entry (entry.id)}
				{#if editingId === entry.id}
					<div class="mb-3 flex flex-col gap-2 rounded border border-accent bg-card-bg p-2.5">
						<input
							type="text"
							class="rounded border border-[#444] bg-bg px-2.5 py-1.5 font-mono text-white"
							bind:value={editTitle}
							use:mention
						/>
						<MarkdownEditor
							content={editBody}
							placeholder="Details"
							minHeight="60px"
							onchange={(md) => editBody = md}
						/>
						<div class="flex gap-2">
							<button
								class="rounded bg-accent px-3 py-1 text-sm font-bold text-white hover:brightness-110"
								onclick={saveEdit}
							>Speichern</button>
							<button
								class="rounded bg-[#444] px-3 py-1 text-sm text-white hover:bg-[#555]"
								onclick={cancelEdit}
							>Abbrechen</button>
						</div>
					</div>
				{:else}
					{@const lines = entry.text.split('\n')}
					{@const title = lines[0]}
					{@const body = lines.slice(1).join('\n').trim()}
					<div class="group mb-3 flex items-start gap-2 rounded bg-card-bg p-2.5">
						<span class="mt-0.5 text-xs text-muted whitespace-nowrap">{formatTime(entry.updatedAt)}</span>
						<div class="flex-1">
							<div class="font-bold">{title}
								{#if entry.linkedContextId}
									<span class="ml-1 inline-block rounded bg-accent/20 px-1.5 py-0.5 text-xs font-normal text-accent">
										{contextNameMap().get(entry.linkedContextId) ?? entry.linkedContextId}
									</span>
								{/if}
							</div>
							{#if body}
								<RenderedMarkdown text={body} class="mt-1 text-sm text-[#ccc]" />
							{/if}
						</div>
						<button
							class="mt-0.5 text-xs text-[#666] opacity-0 transition-opacity group-hover:opacity-100 hover:text-[#ccc]"
							onclick={() => startEdit(entry)}
							title="Bearbeiten"
						>&#9998;</button>
						<button
							class="mt-0.5 text-xs text-[#666] opacity-0 transition-opacity group-hover:opacity-100 hover:text-red-400"
							onclick={() => handleDelete(entry.id)}
							title="Löschen"
						>&times;</button>
					</div>
				{/if}
			{/each}
		</div>
	{:else}
		<div class="text-center text-muted">Keine Einträge für {selectedDate}.</div>
	{/if}
{:else}
	<!-- Meeting contexts: topic history + linked journal entries -->
	{#each meetingByDate() as [date, items]}
		<div class="mb-8 border-l-2 border-[#555] pl-5">
			<div class="mb-4 text-xl font-bold text-accent">{date}</div>
			{#each items as entry}
				<div class="mb-4 rounded bg-card-bg p-2.5">
					<span class="mb-1 block text-xs uppercase tracking-wider text-muted">
						{entry.topicTitle}
						{#if entry.isLinked}
							<span class="ml-1 rounded bg-accent/20 px-1 py-0.5 normal-case text-accent">Journal</span>
						{/if}
					</span>
					<RenderedMarkdown text={entry.text} />
				</div>
			{/each}
		</div>
	{:else}
		<div class="text-center text-muted">Keine Einträge.</div>
	{/each}
{/if}

{#if confirmDeleteId}
	<ConfirmDialog
		message="Eintrag wirklich löschen?"
		onconfirm={confirmDelete}
		oncancel={() => confirmDeleteId = null}
	/>
{/if}
