<script lang="ts">
import { bookmarks_save, bookmarks_store } from "lib/Bookmarks";
import { fs_encode_path, fs_thumbnail_url } from "lib/FilesystemAPI.svelte";
import { highlight_current_page } from "lib/HighlightCurrentPage";
import MenuEntry from "./MenuEntry.svelte";
import { flip } from "svelte/animate";

let editing = $state(false)

const toggle_edit = async () => {
	if (editing) {
		try {
			await bookmarks_save($bookmarks_store)
		} catch (err) {
			alert("Failed to save bookmarks:\n"+err)
		}
	}

	editing = !editing
}

const delete_bookmark = (id: string) => {
	console.debug("Deleting bookmark", id)
	$bookmarks_store = $bookmarks_store.filter((bm) => bm.id !== id)
}

let hovering: number = $state(-1);
const enable_drag = (e: MouseEvent) => {
	(e.target as HTMLElement).closest("div").setAttribute("draggable", "true");
}
const disable_drag = (e: MouseEvent) => {
	(e.target as HTMLElement).closest("div").setAttribute("draggable", "false");
}
const drag = (e: DragEvent, index: number) => {
	if (!editing) {
		e.preventDefault()
		return
	}

	e.dataTransfer.effectAllowed = 'move';
	e.dataTransfer.dropEffect = 'move';
	e.dataTransfer.setData('text/plain', index.toString());
}
const drop = (e: DragEvent, drop_idx: number) => {
	hovering = -1

	if (e.dataTransfer.files.length !== 0) {
		// This is not a rearrangement, this is a file upload
		return
	}

	e.dataTransfer.dropEffect = 'move';
	let drag_idx = parseInt(e.dataTransfer.getData("text/plain"));
	if ($bookmarks_store[drag_idx] === undefined) {
		return
	}

	e.preventDefault()

	// If the drag is up, we will place the item before the drop target. If the
	// drag is down, we place it after the drop target
	if (drag_idx < drop_idx) {
		$bookmarks_store.splice(drop_idx + 1, 0, $bookmarks_store[drag_idx]);
		$bookmarks_store.splice(drag_idx, 1);
	} else if (drag_idx > drop_idx) {
		$bookmarks_store.splice(drop_idx, 0, $bookmarks_store[drag_idx]);
		$bookmarks_store.splice(drag_idx + 1, 1);
	} else {
		return; // Nothing changed
	}

	$bookmarks_store = $bookmarks_store
}
</script>

{#if $bookmarks_store.length !== 0}
	<MenuEntry id="bookmarks">
		{#snippet title()}
			<div class="title">Bookmarks</div>
			<button onclick={toggle_edit} class:button_highlight={editing} class="button flat">
				{#if editing}
					<i class="icon">save</i>
				{:else}
					<i class="icon">edit</i>
				{/if}
			</button>
		{/snippet}

		{#snippet body()}
			{#each $bookmarks_store as bookmark, index (bookmark.id)}
				<div class="row"
					role="button"
					tabindex="0"
					ondragstart={e => drag(e, index)}
					ondrop={e => drop(e, index)}
					ondragover={e => {e.preventDefault(); e.stopPropagation()}}
					ondragenter={() => hovering = index}
					ondragend={() => {hovering = -1}}
					class:highlight={hovering === index}
					animate:flip={{duration: 300}}
				>
					{#if editing}
						<button
							class="button flat"
							style="cursor: grab;"
							onmousedown={enable_drag}
							onmouseup={disable_drag}
						>
							<i class="icon">drag_indicator</i>
						</button>
						<input type="text" bind:value={bookmark.label}/>
						<button onclick={() => delete_bookmark(bookmark.id)}>
							<i class="icon">delete</i>
						</button>
					{:else}
						<a class="button" href="/d{fs_encode_path(bookmark.path)}" use:highlight_current_page>
							<img src={fs_thumbnail_url(bookmark.path, 32, 32)} class="thumbnail" alt="Bookmark icon" />
							<span>{bookmark.label}</span>
						</a>
					{/if}
				</div>
			{/each}
		{/snippet}
	</MenuEntry>
{/if}

<style>
.title {
	flex: 1 1 auto;
}
.row {
	display: flex;
	flex-direction: row;
	align-items: center;
}
.row>a {
	flex: 1 1 auto;
}
.row>button {
	flex: 0 0 auto;
}
.button {
	background: none;
	box-shadow: none;
}
.highlight {
	box-shadow: 0 0 0px 1px var(--highlight_color);
	text-decoration: none;
}
.thumbnail {
	height: 1.5em;
	width: 1.5em;
	border-radius: 2px;
}
</style>
