<script lang="ts">
	/**
	 * Admin — Webhook-administrasjon (oppgave 29.5)
	 *
	 * Opprett, vis, regenerer token og slett webhooks.
	 * Viser aktivitetslogg med siste hendelser per webhook.
	 */
	import { page } from '$app/stores';
	import {
		fetchWebhooks,
		fetchWebhookEvents,
		fetchWebhookTemplates,
		createWebhook,
		regenerateWebhookToken,
		deleteWebhook,
		setWebhookTemplate,
		type WebhookInfo,
		type WebhookEvent,
		type WebhookTemplateInfo
	} from '$lib/api';

	const session = $derived($page.data.session as Record<string, unknown> | undefined);
	const accessToken = $derived(session?.accessToken as string | undefined);

	let webhooks = $state<WebhookInfo[]>([]);
	let loading = $state(false);
	let error = $state<string | null>(null);
	let actionLoading = $state<string | null>(null);

	// Templates
	let templates = $state<WebhookTemplateInfo[]>([]);

	// Opprett-skjema
	let showCreateForm = $state(false);
	let newTitle = $state('');
	let newCollectionId = $state('');
	let newTemplateId = $state('');
	let collections = $state<{ id: string; title: string | null }[]>([]);

	// Hendelser per webhook (utfelt)
	let expandedWebhook = $state<string | null>(null);
	let events = $state<WebhookEvent[]>([]);
	let eventsLoading = $state(false);

	// Kopier-feedback
	let copiedToken = $state<string | null>(null);

	// Poll webhooks every 10 seconds + load templates once
	$effect(() => {
		if (!accessToken) return;
		loadWebhooks();
		loadTemplates();
		const interval = setInterval(loadWebhooks, 10000);
		return () => clearInterval(interval);
	});

	async function loadWebhooks() {
		if (!accessToken) return;
		try {
			const res = await fetchWebhooks(accessToken);
			webhooks = res.webhooks;
			error = null;
		} catch (e) {
			error = String(e);
		}
	}

	async function loadTemplates() {
		if (!accessToken) return;
		try {
			templates = await fetchWebhookTemplates(accessToken);
		} catch {
			// Ikke kritisk
		}
	}

	async function loadCollections() {
		if (!accessToken) return;
		try {
			const BASE_URL = import.meta.env.VITE_API_URL ?? '/api';
			const res = await fetch(
				`${BASE_URL}/query/nodes?kind=collection&limit=200`,
				{ headers: { Authorization: `Bearer ${accessToken}` } }
			);
			if (res.ok) {
				const data = await res.json();
				collections = data.nodes.map((n: Record<string, unknown>) => ({
					id: n.id,
					title: n.title
				}));
			}
		} catch {
			// Ikke kritisk — dropdown blir tom
		}
	}

	function toggleCreateForm() {
		showCreateForm = !showCreateForm;
		if (showCreateForm) loadCollections();
	}

	async function handleCreate() {
		if (!accessToken || !newCollectionId) return;
		actionLoading = 'create';
		error = null;
		try {
			await createWebhook(accessToken, {
				title: newTitle || undefined,
				collection_id: newCollectionId,
				template_id: newTemplateId || undefined
			});
			newTitle = '';
			newCollectionId = '';
			newTemplateId = '';
			showCreateForm = false;
			await loadWebhooks();
		} catch (e) {
			error = String(e);
		} finally {
			actionLoading = null;
		}
	}

	async function handleRegenerateToken(webhookId: string) {
		if (!accessToken) return;
		if (!confirm('Er du sikker? Det gamle tokenet slutter å fungere umiddelbart.')) return;
		actionLoading = `regen-${webhookId}`;
		error = null;
		try {
			await regenerateWebhookToken(accessToken, webhookId);
			await loadWebhooks();
		} catch (e) {
			error = String(e);
		} finally {
			actionLoading = null;
		}
	}

	async function handleDelete(webhookId: string) {
		if (!accessToken) return;
		if (!confirm('Slett webhook permanent? Eksisterende innhold beholdes.')) return;
		actionLoading = `del-${webhookId}`;
		error = null;
		try {
			await deleteWebhook(accessToken, webhookId);
			if (expandedWebhook === webhookId) expandedWebhook = null;
			await loadWebhooks();
		} catch (e) {
			error = String(e);
		} finally {
			actionLoading = null;
		}
	}

	async function toggleEvents(webhookId: string) {
		if (expandedWebhook === webhookId) {
			expandedWebhook = null;
			events = [];
			return;
		}
		if (!accessToken) return;
		expandedWebhook = webhookId;
		eventsLoading = true;
		try {
			events = await fetchWebhookEvents(accessToken, webhookId, 20);
		} catch (e) {
			error = String(e);
		} finally {
			eventsLoading = false;
		}
	}

	async function handleSetTemplate(webhookId: string, templateId: string) {
		if (!accessToken) return;
		actionLoading = `tmpl-${webhookId}`;
		error = null;
		try {
			await setWebhookTemplate(accessToken, webhookId, templateId || null);
			await loadWebhooks();
		} catch (e) {
			error = String(e);
		} finally {
			actionLoading = null;
		}
	}

	function templateName(templateId: string | null): string {
		if (!templateId) return 'Ingen';
		const tmpl = templates.find((t) => t.id === templateId);
		return tmpl ? tmpl.name : templateId;
	}

	async function copyToken(token: string) {
		try {
			await navigator.clipboard.writeText(token);
			copiedToken = token;
			setTimeout(() => { copiedToken = null; }, 2000);
		} catch {
			// Fallback: select teksten
		}
	}

	function webhookUrl(token: string): string {
		return `${window.location.origin}/api/webhook/${token}`;
	}

	function timeAgo(iso: string): string {
		const diff = Date.now() - new Date(iso).getTime();
		const mins = Math.floor(diff / 60000);
		if (mins < 1) return 'nå';
		if (mins < 60) return `${mins}m siden`;
		const hours = Math.floor(mins / 60);
		if (hours < 24) return `${hours}t siden`;
		const days = Math.floor(hours / 24);
		return `${days}d siden`;
	}
</script>

<div class="min-h-screen bg-gray-50">
	<header class="border-b border-gray-200 bg-white">
		<div class="mx-auto flex max-w-3xl items-center justify-between px-4 py-3">
			<div class="flex items-center gap-3">
				<a href="/" class="text-sm text-gray-500 hover:text-gray-700">Hjem</a>
				<a href="/admin" class="text-sm text-gray-500 hover:text-gray-700">Admin</a>
				<h1 class="text-lg font-semibold text-gray-900">Webhooks</h1>
			</div>
			<nav class="flex gap-2 text-sm">
				<a href="/admin" class="rounded-lg bg-gray-100 px-3 py-1.5 text-gray-700 hover:bg-gray-200">
					Vedlikehold
				</a>
				<a href="/admin/jobs" class="rounded-lg bg-gray-100 px-3 py-1.5 text-gray-700 hover:bg-gray-200">
					Jobbkø
				</a>
				<a href="/admin/ai" class="rounded-lg bg-gray-100 px-3 py-1.5 text-gray-700 hover:bg-gray-200">
					AI
				</a>
			</nav>
		</div>
	</header>

	<main class="mx-auto max-w-3xl px-4 py-6">
		{#if !accessToken}
			<p class="text-sm text-gray-400">Logg inn for tilgang.</p>
		{:else}
			<!-- Feilmelding -->
			{#if error}
				<div class="mb-4 rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-700">
					{error}
				</div>
			{/if}

			<!-- Opprett-knapp -->
			<div class="mb-4 flex items-center justify-between">
				<h2 class="text-base font-semibold text-gray-800">
					Webhooks
					<span class="ml-1 text-sm font-normal text-gray-400">({webhooks.length})</span>
				</h2>
				<button
					onclick={toggleCreateForm}
					class="rounded-lg bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700"
				>
					{showCreateForm ? 'Avbryt' : 'Ny webhook'}
				</button>
			</div>

			<!-- Opprett-skjema -->
			{#if showCreateForm}
				<section class="mb-4 rounded-lg border border-blue-200 bg-blue-50 p-4">
					<h3 class="mb-3 text-sm font-semibold text-gray-800">Opprett webhook</h3>
					<div class="space-y-3">
						<div>
							<label for="wh-title" class="mb-1 block text-xs font-medium text-gray-600">
								Navn (valgfritt)
							</label>
							<input
								id="wh-title"
								type="text"
								placeholder="F.eks. GitHub Push"
								bind:value={newTitle}
								class="w-full rounded border border-gray-300 px-2 py-1.5 text-sm"
							/>
						</div>
						<div>
							<label for="wh-template" class="mb-1 block text-xs font-medium text-gray-600">
								Template (valgfritt)
							</label>
							<select
								id="wh-template"
								bind:value={newTemplateId}
								class="w-full rounded border border-gray-300 px-2 py-1.5 text-sm"
							>
								<option value="">Ingen — generisk mapping</option>
								{#each templates as tmpl (tmpl.id)}
									<option value={tmpl.id}>{tmpl.name} — {tmpl.description}</option>
								{/each}
							</select>
						</div>
						<div>
							<label for="wh-collection" class="mb-1 block text-xs font-medium text-gray-600">
								Målsamling
							</label>
							<select
								id="wh-collection"
								bind:value={newCollectionId}
								class="w-full rounded border border-gray-300 px-2 py-1.5 text-sm"
							>
								<option value="">Velg samling...</option>
								{#each collections as col (col.id)}
									<option value={col.id}>{col.title || col.id}</option>
								{/each}
							</select>
						</div>
						<button
							onclick={handleCreate}
							disabled={!newCollectionId || actionLoading === 'create'}
							class="rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50"
						>
							{actionLoading === 'create' ? 'Oppretter...' : 'Opprett'}
						</button>
					</div>
				</section>
			{/if}

			<!-- Webhook-liste -->
			{#if webhooks.length === 0 && !loading}
				<div class="rounded-lg border border-gray-200 bg-white p-8 text-center text-sm text-gray-400">
					Ingen webhooks opprettet ennå.
				</div>
			{:else}
				<div class="space-y-3">
					{#each webhooks as wh (wh.id)}
						<div class="rounded-lg border border-gray-200 bg-white shadow-sm">
							<!-- Webhook-header -->
							<div class="flex items-start justify-between p-4">
								<div class="min-w-0 flex-1">
									<div class="flex items-center gap-2">
										<h3 class="text-sm font-semibold text-gray-800">
											{wh.title || 'Webhook'}
										</h3>
										<span class="rounded-full bg-gray-100 px-2 py-0.5 text-xs text-gray-500">
											{wh.collection_title || wh.collection_id.slice(0, 8)}
										</span>
									</div>

									<!-- Template -->
									<div class="mt-1 flex items-center gap-2">
										<span class="text-xs text-gray-400">Template:</span>
										<select
											value={wh.template_id || ''}
											onchange={(e) => handleSetTemplate(wh.id, (e.target as HTMLSelectElement).value)}
											disabled={actionLoading === `tmpl-${wh.id}`}
											class="rounded border border-gray-200 px-1.5 py-0.5 text-xs text-gray-600 disabled:opacity-50"
										>
											<option value="">Ingen</option>
											{#each templates as tmpl (tmpl.id)}
												<option value={tmpl.id}>{tmpl.name}</option>
											{/each}
										</select>
									</div>

									<!-- Token -->
									<div class="mt-2 flex items-center gap-2">
										<code class="rounded bg-gray-100 px-2 py-0.5 text-xs text-gray-600">
											{wh.token}
										</code>
										<button
											onclick={() => copyToken(wh.token)}
											class="text-xs text-blue-600 hover:text-blue-800"
											title="Kopier token"
										>
											{copiedToken === wh.token ? 'Kopiert!' : 'Kopier'}
										</button>
									</div>

									<!-- URL -->
									<div class="mt-1 flex items-center gap-2">
										<span class="text-xs text-gray-400">URL:</span>
										<code class="truncate rounded bg-gray-50 px-1.5 py-0.5 text-xs text-gray-500">
											{webhookUrl(wh.token)}
										</code>
										<button
											onclick={() => copyToken(webhookUrl(wh.token))}
											class="shrink-0 text-xs text-blue-600 hover:text-blue-800"
										>
											Kopier
										</button>
									</div>

									<!-- Aktivitet -->
									<div class="mt-2 flex items-center gap-4 text-xs text-gray-400">
										<span>{wh.event_count} hendelser</span>
										{#if wh.last_event_at}
											<span>Siste: {timeAgo(wh.last_event_at)}</span>
										{:else}
											<span>Ingen hendelser ennå</span>
										{/if}
										<span>Opprettet {new Date(wh.created_at).toLocaleDateString('nb-NO')}</span>
									</div>
								</div>

								<!-- Handlinger -->
								<div class="ml-3 flex shrink-0 gap-2">
									<button
										onclick={() => toggleEvents(wh.id)}
										class="rounded bg-gray-100 px-2 py-1 text-xs text-gray-600 hover:bg-gray-200"
									>
										{expandedWebhook === wh.id ? 'Skjul' : 'Logg'}
									</button>
									<button
										onclick={() => handleRegenerateToken(wh.id)}
										disabled={actionLoading === `regen-${wh.id}`}
										class="rounded bg-amber-100 px-2 py-1 text-xs text-amber-700 hover:bg-amber-200 disabled:opacity-50"
									>
										{actionLoading === `regen-${wh.id}` ? '...' : 'Nytt token'}
									</button>
									<button
										onclick={() => handleDelete(wh.id)}
										disabled={actionLoading === `del-${wh.id}`}
										class="rounded bg-red-100 px-2 py-1 text-xs text-red-700 hover:bg-red-200 disabled:opacity-50"
									>
										{actionLoading === `del-${wh.id}` ? '...' : 'Slett'}
									</button>
								</div>
							</div>

							<!-- Hendelseslogg (utfelt) -->
							{#if expandedWebhook === wh.id}
								<div class="border-t border-gray-100 bg-gray-50 px-4 py-3">
									<h4 class="mb-2 text-xs font-semibold text-gray-600">Siste hendelser</h4>
									{#if eventsLoading}
										<p class="text-xs text-gray-400">Laster...</p>
									{:else if events.length === 0}
										<p class="text-xs text-gray-400">Ingen hendelser registrert.</p>
									{:else}
										<div class="max-h-64 space-y-2 overflow-y-auto">
											{#each events as ev (ev.node_id)}
												<div class="rounded border border-gray-200 bg-white px-3 py-2">
													<div class="flex items-center justify-between text-xs">
														<span class="font-medium text-gray-700">
															{ev.title || 'Uten tittel'}
														</span>
														<span class="text-gray-400">
															{timeAgo(ev.created_at)}
														</span>
													</div>
													{#if ev.payload}
														<pre class="mt-1 max-h-20 overflow-auto rounded bg-gray-50 p-1.5 text-xs text-gray-500">{JSON.stringify(ev.payload, null, 2)}</pre>
													{/if}
												</div>
											{/each}
										</div>
									{/if}
								</div>
							{/if}
						</div>
					{/each}
				</div>
			{/if}
		{/if}
	</main>
</div>
