<script lang="ts">
	import { api } from '$lib/api';
	import { user } from '$lib/user';
	import { get } from 'svelte/store';
	import { onMount } from 'svelte';
	import type { Neuigkeit, Gruppe, Termin } from '$lib/types';

	const canPost = () => true; // alle eingeloggten User dürfen posten
	const userId  = () => get(user)?.id as string;

	let neuigkeiten  = $state<Neuigkeit[]>([]);
	let gruppen      = $state<Gruppe[]>([]);
	let termine      = $state<Termin[]>([]);
	let reaktionen   = $state<Record<string, number>>({});  // beitrag_id → count
	let meineReaktion = $state<Record<string, string>>({});  // beitrag_id → reaktion_id
	let loading      = $state(true);

	// Formular
	let showForm    = $state(false);
	let fText       = $state('');
	let fGruppeIds  = $state<string[]>([]);
	let fTerminId   = $state('');
	let fDateien    = $state<FileList | null>(null);
	let previews    = $state<string[]>([]);
	let saving      = $state(false);
	let formError   = $state('');

	// Lightbox
	let lightboxUrl  = $state('');
	let ladeError    = $state('');

	onMount(async () => {
		try {
			// Queries einzeln damit ein Fehler sichtbar wird
			const [nList, gList] = await Promise.all([
				api.get<Neuigkeit[]>('/neuigkeiten', { sort: '-created' }),
				api.get<Gruppe[]>('/gruppen', { sort: 'name' }),
			]);
			neuigkeiten = nList;
			gruppen     = gList;

			// Termine der letzten 30 Tage + zukünftige
			try {
				termine = await api.get<Termin[]>('/termine', { sort: '-beginn' });
			} catch { termine = []; }

			// Reaktionen – separat damit Fehler nicht alles blockiert
			try {
				const [rList, meineList] = await Promise.all([
					api.get<any[]>('/reaktionen'),
					api.get<any[]>('/reaktionen', { meine: 'true' }),
				]);
				const counts: Record<string, number> = {};
				for (const r of rList) counts[r.beitrag_id] = (counts[r.beitrag_id] ?? 0) + 1;
				reaktionen = counts;
				const mine: Record<string, string> = {};
				for (const r of meineList) mine[r.beitrag_id] = r.id;
				meineReaktion = mine;
			} catch { /* keine Reaktionen = kein Problem */ }

		} catch (e: unknown) {
			ladeError = e instanceof Error ? e.message : 'Ladefehler';
		} finally {
			loading = false;
		}
	});

	function handleDateiAuswahl(e: Event) {
		const files = (e.target as HTMLInputElement).files;
		fDateien = files;
		previews = [];
		if (!files) return;
		for (const file of Array.from(files)) {
			if (file.type.startsWith('image/')) {
				previews.push(URL.createObjectURL(file));
			} else {
				previews.push(''); // Video – kein Preview
			}
		}
	}

	function toggleGruppe(id: string) {
		fGruppeIds = fGruppeIds.includes(id)
			? fGruppeIds.filter(g => g !== id)
			: [...fGruppeIds, id];
	}

	async function posten() {
		if (!fText.trim() && (!fDateien || fDateien.length === 0)) {
			formError = 'Text oder Foto ist Pflicht.';
			return;
		}
		formError = ''; saving = true;
		try {
			const u = get(user);
			const form = new FormData();
			form.append('autor_name', u?.name ?? '');
			if (fText.trim()) form.append('text', fText.trim());
			if (fTerminId) form.append('termin_id', fTerminId);
			for (const id of fGruppeIds) form.append('gruppe_ids', id);
			if (fDateien) {
				for (const file of Array.from(fDateien)) form.append('medien', file);
			}

			const neu = await api.postForm<Neuigkeit>('/neuigkeiten', form);
			neuigkeiten = [neu, ...neuigkeiten];
			showForm = false;
			fText = ''; fGruppeIds = []; fTerminId = ''; fDateien = null; previews = [];
		} catch (e: unknown) {
			formError = e instanceof Error ? e.message : 'Fehler beim Posten.';
		} finally {
			saving = false;
		}
	}

	async function loeschen(n: Neuigkeit) {
		if (!confirm('Beitrag löschen?')) return;
		await api.del('/neuigkeiten/' + n.id);
		neuigkeiten = neuigkeiten.filter(x => x.id !== n.id);
	}

	async function toggleReaktion(n: Neuigkeit) {
		if (meineReaktion[n.id]) {
			await api.del('/reaktionen/' + meineReaktion[n.id]);
			meineReaktion = { ...meineReaktion, [n.id]: '' };
			reaktionen = { ...reaktionen, [n.id]: Math.max(0, (reaktionen[n.id] ?? 1) - 1) };
		} else {
			const r = await api.post<{ id: string }>('/reaktionen', { beitrag_id: n.id });
			meineReaktion = { ...meineReaktion, [n.id]: r.id };
			reaktionen = { ...reaktionen, [n.id]: (reaktionen[n.id] ?? 0) + 1 };
		}
	}

	function mediaUrl(n: Neuigkeit, datei: string, thumb = false): string {
		return api.fileUrl(n.verein_id, n.id, datei, thumb);
	}

	function isVideo(datei: string): boolean {
		return /\.(mp4|mov|m4v)$/i.test(datei);
	}

	function zeitAgo(iso: string): string {
		const diff = Date.now() - new Date(iso).getTime();
		const min = Math.floor(diff / 60000);
		if (min < 1) return 'gerade eben';
		if (min < 60) return `vor ${min} Min.`;
		const h = Math.floor(min / 60);
		if (h < 24) return `vor ${h} Std.`;
		const d = Math.floor(h / 24);
		if (d < 7) return `vor ${d} Tag${d > 1 ? 'en' : ''}`;
		return new Date(iso).toLocaleDateString('de-DE', { day: '2-digit', month: 'short' });
	}

	function autorName(n: Neuigkeit): string {
		return n.autor_name || 'Unbekannt';
	}

	function terminName(id: string): string {
		return termine.find(t => t.id === id)?.titel ?? '';
	}
</script>

<svelte:head><title>Neuigkeiten — vereins.haus</title></svelte:head>

<div class="top">
	<h1>Neuigkeiten</h1>
	{#if canPost()}
		<button class="btn-primary" onclick={() => showForm = true}>+ Beitrag</button>
	{/if}
</div>

{#if loading}
	<p class="hint">Laden…</p>
{:else if ladeError}
	<p class="hint" style="color:#dc2626">{ladeError}</p>
{:else if neuigkeiten.length === 0}
	<p class="hint">Noch keine Beiträge – schreib den ersten!</p>
{:else}
	<div class="feed">
		{#each neuigkeiten as n (n.id)}
			<article class="beitrag">
				<div class="beitrag-kopf">
					<div class="avatar">{autorName(n)[0]?.toUpperCase()}</div>
					<div class="beitrag-meta">
						<span class="autor">{autorName(n)}</span>
						<span class="zeit">{zeitAgo(n.created)}</span>
					</div>
					{#if n.autor_id === userId()}
						<button class="btn-del" onclick={() => loeschen(n)}>✕</button>
					{/if}
				</div>

				{#if n.termin_id}
					<div class="termin-tag">📅 {terminName(n.termin_id)}</div>
				{/if}

				{#if n.text}
					<p class="beitrag-text">{n.text}</p>
				{/if}

				{#if n.medien?.length > 0}
					<div class="medien-grid" class:single={n.medien.length === 1}>
						{#each n.medien as datei (datei)}
							{#if isVideo(datei)}
								<video controls class="media-item" preload="metadata">
									<source src={mediaUrl(n, datei)} />
								</video>
							{:else}
								<button
									class="media-btn"
									onclick={() => lightboxUrl = mediaUrl(n, datei)}
								>
									<img
										src={mediaUrl(n, datei, true)}
										alt=""
										class="media-item"
										loading="lazy"
									/>
								</button>
							{/if}
						{/each}
					</div>
				{/if}

				<div class="beitrag-fuss">
					<button
						class="btn-like"
						class:aktiv={!!meineReaktion[n.id]}
						onclick={() => toggleReaktion(n)}
					>
						👍 {reaktionen[n.id] ?? 0}
					</button>
					{#if n.gruppe_ids?.length > 0}
						<span class="gruppe-tag">
							{n.gruppe_ids.length === 1
								? (gruppen.find(g => g.id === n.gruppe_ids[0])?.name ?? '')
								: `${n.gruppe_ids.length} Gruppen`}
						</span>
					{/if}
				</div>
			</article>
		{/each}
	</div>
{/if}

<!-- Beitrag verfassen -->
{#if showForm}
	<div class="overlay" role="dialog" aria-modal="true">
		<div class="sheet">
			<h2>Neuer Beitrag</h2>

			<form onsubmit={(e) => { e.preventDefault(); posten(); }}>
				<div class="field">
					<textarea bind:value={fText} rows="4" placeholder="Was gibt's Neues?"></textarea>
				</div>

				<!-- Foto/Video Upload -->
				<div class="upload-area">
					<label class="upload-label">
						<input
							type="file"
							accept="image/*,video/mp4,video/quicktime"
							multiple
							class="file-input"
							onchange={handleDateiAuswahl}
						/>
						📷 Fotos / Videos hinzufügen
					</label>
					{#if previews.length > 0}
						<div class="preview-grid">
							{#each previews as p, i}
								{#if p}
									<img src={p} alt="" class="preview-img" />
								{:else}
									<div class="preview-video">🎬 Video {i + 1}</div>
								{/if}
							{/each}
						</div>
					{/if}
				</div>

				<!-- Termin verknüpfen -->
				{#if termine.length > 0}
					<div class="field">
						<label for="ftermin">Zum Termin</label>
						<select id="ftermin" bind:value={fTerminId}>
							<option value="">— keinen verknüpfen —</option>
							{#each termine as t (t.id)}
								<option value={t.id}>{t.titel} · {new Date(t.beginn).toLocaleDateString('de-DE')}</option>
							{/each}
						</select>
					</div>
				{/if}

				<!-- Gruppen -->
				{#if gruppen.length > 0}
					<div class="field">
						<span class="field-label">Für Gruppen (leer = alle)</span>
						<div class="checkboxes">
							{#each gruppen as g (g.id)}
								<label class="check-label" class:active={fGruppeIds.includes(g.id)}>
									<input type="checkbox" checked={fGruppeIds.includes(g.id)} onchange={() => toggleGruppe(g.id)} />
									{g.name}
								</label>
							{/each}
						</div>
					</div>
				{/if}

				{#if formError}<p class="error">{formError}</p>{/if}

				<div class="actions">
					<button type="button" class="btn-ghost" onclick={() => showForm = false}>Abbrechen</button>
					<button type="submit" class="btn-primary-full" disabled={saving}>
						{saving ? 'Posten…' : 'Posten'}
					</button>
				</div>
			</form>
		</div>
	</div>
{/if}

<!-- Lightbox -->
{#if lightboxUrl}
	<div class="lightbox" role="button" tabindex="0"
		onclick={() => lightboxUrl = ''}
		onkeydown={(e) => e.key === 'Escape' && (lightboxUrl = '')}>
		<img src={lightboxUrl} alt="" />
	</div>
{/if}

<style>
	.top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.25rem; }
	.top .btn-primary { flex: none; padding: 0.45rem 0.9rem; font-size: 0.875rem; }
	h1 { font-size: 1.4rem; font-weight: 700; color: var(--c-text); }
	.hint { color: var(--c-text-hint); text-align: center; margin-top: 3rem; }

	.feed { display: flex; flex-direction: column; gap: 0.75rem; margin-bottom: 5rem; }

	.beitrag {
		background: var(--c-bg-card); border: 1px solid var(--c-border); border-radius: 12px;
		overflow: hidden; padding: 0.9rem 1rem;
	}

	.beitrag-kopf {
		display: flex; align-items: center; gap: 0.65rem; margin-bottom: 0.6rem;
	}
	.avatar {
		width: 2.2rem; height: 2.2rem; border-radius: 50%;
		background: var(--c-primary-light); color: var(--c-primary);
		display: flex; align-items: center; justify-content: center;
		font-weight: 700; font-size: 0.85rem; flex-shrink: 0;
	}
	.beitrag-meta { flex: 1; display: flex; flex-direction: column; gap: 0.05rem; }
	.autor { font-weight: 600; font-size: 0.875rem; color: var(--c-text); }
	.zeit  { font-size: 0.72rem; color: var(--c-text-hint); }
	.btn-del {
		background: none; border: none; color: var(--c-text-hint);
		font-size: 0.85rem; cursor: pointer; padding: 0.2rem;
	}
	.btn-del:hover { color: var(--c-error); }

	.termin-tag {
		font-size: 0.75rem; color: var(--c-primary); background: var(--c-primary-subtle);
		border-radius: 20px; padding: 0.2rem 0.65rem;
		display: inline-block; margin-bottom: 0.5rem;
	}

	.beitrag-text {
		font-size: 0.92rem; color: var(--c-text); line-height: 1.55;
		white-space: pre-wrap; margin: 0 0 0.6rem;
	}

	/* Medien-Grid */
	.medien-grid {
		display: grid;
		grid-template-columns: repeat(2, 1fr);
		gap: 0.25rem;
		border-radius: 8px;
		overflow: hidden;
		margin-bottom: 0.6rem;
	}
	.medien-grid.single { grid-template-columns: 1fr; }
	.media-btn {
		display: block; padding: 0; background: none; border: none;
		cursor: pointer; overflow: hidden;
	}
	.media-item {
		width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block;
		transition: opacity 0.15s;
	}
	.media-btn:hover .media-item { opacity: 0.9; }

	.beitrag-fuss {
		display: flex; align-items: center; gap: 0.75rem; padding-top: 0.5rem;
		border-top: 1px solid var(--c-bg); margin-top: 0.25rem;
	}
	.btn-like {
		background: none; border: 1px solid var(--c-border); border-radius: 20px;
		padding: 0.25rem 0.75rem; font-size: 0.82rem; cursor: pointer;
		transition: all 0.15s; color: var(--c-text-muted);
	}
	.btn-like.aktiv { background: var(--c-warning-bg); border-color: var(--c-warning); color: var(--c-warning-dark); }
	.gruppe-tag { font-size: 0.72rem; color: var(--c-text-hint); }

	/* Formular */
	.overlay {
		position: fixed; inset: 0; background: rgba(0,0,0,0.4);
		display: flex; align-items: flex-end; justify-content: center;
		z-index: 100; padding: 1rem; padding-bottom: calc(1rem + env(safe-area-inset-bottom));
	}
	.sheet {
		background: var(--c-bg-card); border-radius: 16px; padding: 1.5rem;
		width: 100%; max-width: 480px; max-height: 92dvh; overflow-y: auto;
	}
	h2 { font-size: 1.1rem; font-weight: 700; color: var(--c-text); margin-bottom: 1rem; }
	.field { display: flex; flex-direction: column; gap: 0.3rem; margin-bottom: 0.85rem; }
	label, .field-label { font-size: 0.875rem; font-weight: 500; color: var(--c-text-secondary); }
	textarea, select {
		padding: 0.65rem 0.85rem; border: 1.5px solid var(--c-border); border-radius: 8px;
		font-size: 1rem; background: var(--c-bg-card); width: 100%;
		box-sizing: border-box; font-family: inherit; resize: vertical;
		transition: border-color 0.15s;
	}
	textarea:focus, select:focus { outline: none; border-color: var(--c-primary); }

	.upload-area { margin-bottom: 0.85rem; }
	.upload-label {
		display: inline-flex; align-items: center; gap: 0.4rem;
		padding: 0.5rem 0.85rem; border: 1.5px dashed var(--c-border); border-radius: 8px;
		font-size: 0.875rem; color: var(--c-text-muted); cursor: pointer;
		transition: border-color 0.15s;
	}
	.upload-label:hover { border-color: var(--c-primary); color: var(--c-primary); }
	.file-input { display: none; }
	.preview-grid {
		display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem;
	}
	.preview-img { width: 72px; height: 72px; object-fit: cover; border-radius: 6px; }
	.preview-video {
		width: 72px; height: 72px; background: var(--c-bg); border-radius: 6px;
		display: flex; align-items: center; justify-content: center;
		font-size: 0.75rem; color: var(--c-text-muted);
	}

	.checkboxes { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.25rem; }
	.check-label {
		display: flex; align-items: center; gap: 0.35rem;
		padding: 0.3rem 0.65rem; border: 1.5px solid var(--c-border); border-radius: 20px;
		font-size: 0.82rem; cursor: pointer;
	}
	.check-label.active { border-color: var(--c-primary); background: var(--c-primary-light); color: var(--c-primary); }
	.check-label input { display: none; }

	.error { color: var(--c-error); font-size: 0.875rem; margin-bottom: 0.5rem; }
	.actions { display: flex; gap: 0.75rem; margin-top: 0.5rem; }
	.btn-primary-full {
		flex: 1; padding: 0.75rem; background: var(--c-primary); color: var(--c-bg-card);
		border: none; border-radius: 8px; font-size: 1rem; font-weight: 600; cursor: pointer;
	}
	.btn-primary-full:disabled { opacity: 0.55; cursor: not-allowed; }
	.btn-ghost {
		padding: 0.75rem 1rem; background: none;
		border: 1.5px solid var(--c-border); border-radius: 8px;
		font-size: 1rem; color: var(--c-text-muted); cursor: pointer;
	}
	.btn-primary { background: var(--c-primary); color: var(--c-bg-card); border: none; border-radius: 8px; font-weight: 600; cursor: pointer; }

	/* Lightbox */
	.lightbox {
		position: fixed; inset: 0; background: rgba(0,0,0,0.9);
		display: flex; align-items: center; justify-content: center;
		z-index: 200; cursor: zoom-out;
	}
	.lightbox img { max-width: 95vw; max-height: 90dvh; border-radius: 8px; }
</style>
