<script lang="ts">
	import { onMount } from 'svelte';

	let { props = {} }: { props?: Record<string, unknown> } = $props();

	interface Entity {
		id: string;
		name: string;
		type: string;
		aliases: string[];
		avatar_url: string | null;
		edge_count?: string;
		created_at: string;
	}

	interface Edge {
		edge_id: string;
		source_id: string;
		target_id: string;
		relation_type: string;
		relation_label: string;
		connected_name: string;
		connected_type: string;
		connected_id: string;
	}

	let entities = $state<Entity[]>([]);
	let loading = $state(true);
	let error = $state('');
	let query = $state('');
	let typeFilter = $state('');

	// Opprett-skjema
	let showCreate = $state(false);
	let newName = $state('');
	let newType = $state('person');
	let newAliases = $state('');

	// Detalj-visning
	let selected = $state<Entity | null>(null);
	let selectedEdges = $state<Edge[]>([]);
	let loadingEdges = $state(false);

	// Redigering
	let editing = $state(false);
	let editName = $state('');
	let editType = $state('');
	let editAliases = $state('');

	const entityTypes = ['person', 'organisasjon', 'sted', 'tema', 'konsept'];
	const typeColors: Record<string, string> = {
		person: '#3b82f6',
		organisasjon: '#f59e0b',
		sted: '#10b981',
		tema: '#8b5cf6',
		konsept: '#ec4899'
	};

	let searchTimeout: ReturnType<typeof setTimeout>;

	function debounceSearch() {
		clearTimeout(searchTimeout);
		searchTimeout = setTimeout(fetchEntities, 200);
	}

	async function fetchEntities() {
		try {
			const params = new URLSearchParams();
			if (query) params.set('q', query);
			if (typeFilter) params.set('type', typeFilter);
			const res = await fetch(`/api/entities?${params}`);
			if (!res.ok) throw new Error('Feil ved henting');
			entities = await res.json();
		} catch (e) {
			error = (e as Error).message;
		} finally {
			loading = false;
		}
	}

	async function createEntity() {
		if (!newName.trim()) return;
		const res = await fetch('/api/entities', {
			method: 'POST',
			headers: { 'Content-Type': 'application/json' },
			body: JSON.stringify({
				name: newName.trim(),
				type: newType,
				aliases: newAliases.split(',').map(a => a.trim()).filter(Boolean)
			})
		});
		if (res.ok) {
			newName = '';
			newAliases = '';
			showCreate = false;
			fetchEntities();
		}
	}

	async function selectEntity(entity: Entity) {
		selected = entity;
		editing = false;
		loadingEdges = true;
		try {
			const res = await fetch(`/api/entities/${entity.id}/edges`);
			selectedEdges = res.ok ? await res.json() : [];
		} catch {
			selectedEdges = [];
		} finally {
			loadingEdges = false;
		}
	}

	function startEdit() {
		if (!selected) return;
		editing = true;
		editName = selected.name;
		editType = selected.type;
		editAliases = selected.aliases.join(', ');
	}

	async function saveEdit() {
		if (!selected) return;
		const res = await fetch(`/api/entities/${selected.id}`, {
			method: 'PATCH',
			headers: { 'Content-Type': 'application/json' },
			body: JSON.stringify({
				name: editName.trim(),
				type: editType,
				aliases: editAliases.split(',').map(a => a.trim()).filter(Boolean)
			})
		});
		if (res.ok) {
			const updated = await res.json();
			selected = { ...selected, ...updated };
			editing = false;
			fetchEntities();
		}
	}

	async function deleteEntity() {
		if (!selected) return;
		const res = await fetch(`/api/entities/${selected.id}`, { method: 'DELETE' });
		if (res.ok) {
			selected = null;
			fetchEntities();
		}
	}

	async function deleteEdge(edgeId: string) {
		const res = await fetch(`/api/graph/edges/${edgeId}`, { method: 'DELETE' });
		if (res.ok && selected) {
			selectEntity(selected);
		}
	}

	onMount(fetchEntities);
</script>

{#if selected}
	<!-- Detalj-visning -->
	<div class="detail">
		<button type="button" class="back-btn" onclick={() => { selected = null; }}>
			&larr; Tilbake
		</button>

		{#if editing}
			<div class="edit-form">
				<input type="text" bind:value={editName} placeholder="Navn" class="input" />
				<select bind:value={editType} class="input">
					{#each entityTypes as t}<option value={t}>{t}</option>{/each}
				</select>
				<input type="text" bind:value={editAliases} placeholder="Aliaser (kommaseparert)" class="input" />
				<div class="actions">
					<button type="button" class="btn primary" onclick={saveEdit}>Lagre</button>
					<button type="button" class="btn" onclick={() => { editing = false; }}>Avbryt</button>
				</div>
			</div>
		{:else}
			<div class="entity-header">
				<span class="type-badge" style:background={typeColors[selected.type] ?? '#8b92a5'}>
					{selected.type}
				</span>
				<h3 class="entity-name">{selected.name}</h3>
				{#if selected.aliases.length > 0}
					<div class="aliases">
						{#each selected.aliases as alias}
							<span class="alias">{alias}</span>
						{/each}
					</div>
				{/if}
				<div class="actions">
					<button type="button" class="btn" onclick={startEdit}>Rediger</button>
					<button type="button" class="btn danger" onclick={deleteEntity}>Slett</button>
				</div>
			</div>

			<div class="edges-section">
				<h4 class="section-title">Relasjoner</h4>
				{#if loadingEdges}
					<p class="muted">Laster...</p>
				{:else if selectedEdges.length === 0}
					<p class="muted">Ingen relasjoner</p>
				{:else}
					{#each selectedEdges as edge (edge.edge_id)}
						<div class="edge-row">
							<span class="edge-label">{edge.relation_label}</span>
							<button
								type="button"
								class="edge-target"
								onclick={() => {
									const target = entities.find(e => e.id === edge.connected_id);
									if (target) selectEntity(target);
								}}
							>
								{edge.connected_name}
							</button>
							<span class="edge-type-badge" style:background={typeColors[edge.connected_type] ?? '#8b92a5'}>
								{edge.connected_type}
							</span>
							<button type="button" class="edge-delete" onclick={() => deleteEdge(edge.edge_id)}>&times;</button>
						</div>
					{/each}
				{/if}
			</div>
		{/if}
	</div>
{:else}
	<!-- Liste-visning -->
	<div class="list-view">
		<div class="search-row">
			<input
				type="text"
				placeholder="Søk entiteter..."
				bind:value={query}
				oninput={debounceSearch}
				class="input search"
			/>
			<select bind:value={typeFilter} onchange={fetchEntities} class="input type-select">
				<option value="">Alle typer</option>
				{#each entityTypes as t}<option value={t}>{t}</option>{/each}
			</select>
			<button type="button" class="btn primary" onclick={() => { showCreate = !showCreate; }}>+</button>
		</div>

		{#if showCreate}
			<div class="create-form">
				<input type="text" bind:value={newName} placeholder="Navn" class="input" />
				<select bind:value={newType} class="input">
					{#each entityTypes as t}<option value={t}>{t}</option>{/each}
				</select>
				<input type="text" bind:value={newAliases} placeholder="Aliaser (kommaseparert)" class="input" />
				<div class="actions">
					<button type="button" class="btn primary" onclick={createEntity} disabled={!newName.trim()}>Opprett</button>
					<button type="button" class="btn" onclick={() => { showCreate = false; }}>Avbryt</button>
				</div>
			</div>
		{/if}

		{#if loading}
			<p class="muted center">Laster...</p>
		{:else if entities.length === 0}
			<p class="muted center">{query ? 'Ingen treff' : 'Ingen entiteter ennå'}</p>
		{:else}
			<div class="entity-list">
				{#each entities as entity (entity.id)}
					<button type="button" class="entity-row" onclick={() => selectEntity(entity)}>
						<span class="type-dot" style:background={typeColors[entity.type] ?? '#8b92a5'}></span>
						<span class="entity-row-name">{entity.name}</span>
						{#if entity.aliases.length > 0}
							<span class="entity-row-alias">{entity.aliases[0]}</span>
						{/if}
						<span class="entity-row-type">{entity.type}</span>
					</button>
				{/each}
			</div>
		{/if}
	</div>
{/if}

{#if error}
	<div class="error-msg">{error}</div>
{/if}

<style>
	.list-view, .detail {
		display: flex;
		flex-direction: column;
		gap: 0.5rem;
		height: 100%;
		min-height: 0;
	}

	.search-row {
		display: flex;
		gap: 0.35rem;
	}

	.search {
		flex: 1;
	}

	.type-select {
		width: 110px;
	}

	.input {
		background: #0f1117;
		border: 1px solid #2d3148;
		border-radius: 6px;
		color: #e1e4e8;
		padding: 0.4rem 0.5rem;
		font-size: 0.8rem;
		font-family: inherit;
	}

	.input:focus {
		outline: none;
		border-color: #3b82f6;
	}

	.input::placeholder {
		color: #8b92a5;
	}

	select.input {
		cursor: pointer;
	}

	.btn {
		background: #1e2235;
		border: 1px solid #2d3148;
		border-radius: 6px;
		color: #8b92a5;
		padding: 0.4rem 0.6rem;
		font-size: 0.8rem;
		cursor: pointer;
		font-family: inherit;
		white-space: nowrap;
	}

	.btn:hover { background: #2d3148; color: #e1e4e8; }
	.btn.primary { background: #3b82f6; color: white; border-color: #3b82f6; }
	.btn.primary:hover { background: #2563eb; }
	.btn.primary:disabled { opacity: 0.5; cursor: default; }
	.btn.danger { background: #dc2626; color: white; border-color: #dc2626; }
	.btn.danger:hover { background: #b91c1c; }

	.create-form, .edit-form {
		display: flex;
		flex-direction: column;
		gap: 0.35rem;
		padding: 0.5rem;
		background: #0f1117;
		border-radius: 6px;
	}

	.actions {
		display: flex;
		gap: 0.35rem;
	}

	.entity-list {
		flex: 1;
		overflow-y: auto;
		display: flex;
		flex-direction: column;
		gap: 2px;
	}

	.entity-row {
		display: flex;
		align-items: center;
		gap: 0.5rem;
		padding: 0.4rem 0.5rem;
		border: none;
		background: none;
		color: #e1e4e8;
		font-family: inherit;
		font-size: 0.8rem;
		cursor: pointer;
		border-radius: 4px;
		text-align: left;
		width: 100%;
	}

	.entity-row:hover {
		background: #1e2235;
	}

	.type-dot {
		width: 8px;
		height: 8px;
		border-radius: 50%;
		flex-shrink: 0;
	}

	.entity-row-name {
		flex: 1;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.entity-row-alias {
		color: #8b92a5;
		font-size: 0.7rem;
	}

	.entity-row-type {
		color: #8b92a5;
		font-size: 0.7rem;
		flex-shrink: 0;
	}

	/* Detalj */
	.back-btn {
		background: none;
		border: none;
		color: #3b82f6;
		cursor: pointer;
		font-size: 0.8rem;
		padding: 0;
		font-family: inherit;
		text-align: left;
	}

	.back-btn:hover { text-decoration: underline; }

	.entity-header {
		display: flex;
		flex-direction: column;
		gap: 0.35rem;
	}

	.type-badge {
		display: inline-block;
		padding: 0.15rem 0.4rem;
		border-radius: 4px;
		font-size: 0.7rem;
		color: white;
		font-weight: 600;
		text-transform: uppercase;
		align-self: flex-start;
	}

	.entity-name {
		font-size: 1.1rem;
		color: #e1e4e8;
		margin: 0;
		font-weight: 600;
	}

	.aliases {
		display: flex;
		gap: 0.25rem;
		flex-wrap: wrap;
	}

	.alias {
		background: #1e2235;
		color: #8b92a5;
		padding: 0.1rem 0.4rem;
		border-radius: 4px;
		font-size: 0.7rem;
	}

	.edges-section {
		flex: 1;
		overflow-y: auto;
		margin-top: 0.5rem;
	}

	.section-title {
		font-size: 0.75rem;
		color: #8b92a5;
		text-transform: uppercase;
		letter-spacing: 0.03em;
		margin: 0 0 0.35rem;
		font-weight: 600;
	}

	.edge-row {
		display: flex;
		align-items: center;
		gap: 0.35rem;
		padding: 0.3rem 0;
		font-size: 0.8rem;
		border-bottom: 1px solid #1e2235;
	}

	.edge-label {
		color: #8b92a5;
		font-size: 0.7rem;
		flex-shrink: 0;
	}

	.edge-target {
		color: #3b82f6;
		background: none;
		border: none;
		cursor: pointer;
		font-size: 0.8rem;
		font-family: inherit;
		padding: 0;
		flex: 1;
		text-align: left;
	}

	.edge-target:hover { text-decoration: underline; }

	.edge-type-badge {
		padding: 0.1rem 0.3rem;
		border-radius: 3px;
		font-size: 0.6rem;
		color: white;
		flex-shrink: 0;
	}

	.edge-delete {
		background: none;
		border: none;
		color: #8b92a5;
		cursor: pointer;
		font-size: 1rem;
		padding: 0 0.2rem;
		line-height: 1;
	}

	.edge-delete:hover { color: #f87171; }

	.muted { color: #8b92a5; font-size: 0.8rem; margin: 0; }
	.center { text-align: center; padding: 2rem 0; }
	.error-msg { color: #f87171; font-size: 0.75rem; padding: 0.25rem; }
</style>
