<script lang="ts">
	import type { NoteMetadata, FullNote } from "$lib/client"
	import Close from "$lib/icons/Close.svelte"
	import CreateNew from "$lib/icons/CreateNew.svelte"
	import Logout from "$lib/icons/Logout.svelte"
	import Search from "$lib/icons/Search.svelte"
	import Settings from "$lib/icons/Settings.svelte"

	// Props
	export let sidebarOpen = true
	export let notes: NoteMetadata[] = []
	export let currentNote: FullNote | null = null
	export let toggleSettings: () => void
	export let logout: () => Promise<void>
	export let createNewNote: () => Promise<void>
	export let selectNote: (noteId: string, fetchRemote: boolean) => Promise<void>

	const formatDate = (dateString: string | Date): string => {
		if (!dateString) {
			return ""
		}

		const d = new Date(dateString)
		return d.toLocaleDateString(undefined, {
			weekday: "short",
			year: "2-digit",
			month: "short",
			day: "numeric",
			hour: "numeric",
			minute: "numeric"
		})
	}

	const closeSidebar = () => {
		sidebarOpen = false
	}

	const handleNoteKeydown = (event: KeyboardEvent, noteID: string) => {
		if (event.key === "Enter" || event.key === " ") {
			event.preventDefault() // Prevent page scroll on space
			selectNote(noteID, true) // Sync with API due to pushing updates
		}
	}

	// Client-side search
	let searchQuery = ""
	$: filteredNotes = searchQuery
		? notes.filter((note) => note.title.toLowerCase().includes(searchQuery.toLowerCase()))
		: notes
</script>

<!-- TODO: add admin modal button (+ component similar to the settings modal) if the user is an admin -->
<!-- TODO: component-level paging support (via the implementation in `pages.ts`) -->

<aside
	class="sidebar z-10"
	class:translate-x-0={sidebarOpen}
	class:translate-x-[-100%]={!sidebarOpen}
	class:fixed={true}
	class:md:relative={true}
>
	<!-- Sidebar header -->
	<div class="sidebar-header">
		<div class="flex items-center justify-between">
			<button
				on:click={createNewNote}
				class="btn-primary rounded-full p-2"
				aria-label="Create new note"
			>
				<CreateNew />
			</button>

			<!-- Search bar -->
			<div class="relative pl-4">
				<input type="text" placeholder="Search" bind:value={searchQuery} class="search-bar" />
				<Search />
			</div>

			<!-- Close button visible only on mobile -->
			<div class="relative pl-4">
				<button
					on:click={closeSidebar}
					class="btn-secondary rounded-full p-2 md:hidden"
					aria-label="Close sidebar"
				>
					<Close />
				</button>
			</div>
		</div>
	</div>

	<!-- Notes list -->
	<div class="flex-1 overflow-y-auto">
		{#if filteredNotes.length > 0}
			<ul class="sidebar-divider" role="listbox">
				{#each filteredNotes as note}
					<li
						class="sidebar-item"
						class:sidebar-item-active={currentNote && note.id === currentNote.id}
						on:click={() => selectNote(note.id, false)}
						on:keydown={(e) => handleNoteKeydown(e, note.id)}
						tabindex="0"
						role="option"
						aria-selected={currentNote && note.id === currentNote.id}
					>
						<h3 class="truncate font-bold">{note.title || "Untitled Note"}</h3>
						<p class="sidebar-item-text mt-1 italic">
							{formatDate(note.updatedAt)}
						</p>
					</li>
				{/each}
			</ul>
		{:else}
			<div class="sidebar-item-text p-4 text-center">
				{searchQuery ? "No notes match your search" : "No notes yet"}
			</div>
		{/if}
	</div>

	<!-- Sidebar footer -->
	<div class="sidebar-footer">
		<div class="flex justify-between">
			<button on:click={logout} class="btn-secondary rounded-full p-2" aria-label="Logout">
				<Logout />
			</button>

			<!-- It's better for UX that the logout button isn't on the right side -->

			<button
				on:click={toggleSettings}
				class="btn-secondary rounded-full p-2"
				aria-label="Toggle settings"
			>
				<Settings />
			</button>
		</div>
	</div>
</aside>
