<script lang="ts" module>
	let isOpen = $state(false);

	export function closeMobileNav() {
		isOpen = false;
	}
</script>

<script lang="ts">
	import { browser } from "$app/environment";
	import { beforeNavigate } from "$app/navigation";
	import { base } from "$app/paths";
	import { page } from "$app/state";
	import IconNew from "$lib/components/icons/IconNew.svelte";
	import IconShare from "$lib/components/icons/IconShare.svelte";
	import IconBurger from "$lib/components/icons/IconBurger.svelte";
	import { Spring } from "svelte/motion";
	import { shareModal } from "$lib/stores/shareModal";
	import { loading } from "$lib/stores/loading";
	import { requireAuthUser } from "$lib/utils/auth";
	interface Props {
		title: string | undefined;
		children?: import("svelte").Snippet;
	}

	let { title = $bindable(), children }: Props = $props();

	let closeEl: HTMLButtonElement | undefined = $state();
	let openEl: HTMLButtonElement | undefined = $state();

	const isHuggingChat = $derived(Boolean(page.data?.publicConfig?.isHuggingChat));
	const canShare = $derived(
		isHuggingChat &&
			!$loading &&
			Boolean(page.params?.id) &&
			page.route.id?.startsWith("/conversation/")
	);

	// Define the width for the drawer (less than 100% to create the gap)
	const drawerWidthPercentage = 85;

	const tween = Spring.of(
		() => {
			if (isOpen) {
				return 0 as number;
			}
			return -100 as number;
		},
		{ stiffness: 0.2, damping: 0.8 }
	);

	$effect(() => {
		title ??= "New Chat";
	});

	beforeNavigate(() => {
		isOpen = false;
	});

	let shouldFocusClose = $derived(isOpen && closeEl);
	let shouldRefocusOpen = $derived(!isOpen && browser && document.activeElement === closeEl);

	$effect(() => {
		if (shouldFocusClose) {
			closeEl?.focus();
		} else if (shouldRefocusOpen) {
			openEl?.focus();
		}
	});

	// Function to close the drawer when background is tapped
	function closeDrawer() {
		isOpen = false;
	}
</script>

<nav
	class="flex h-12 items-center justify-between rounded-b-xl border-b bg-gray-50 px-3 dark:border-gray-800 dark:bg-gray-800/30 dark:shadow-xl md:hidden"
>
	<button
		type="button"
		class="-ml-3 flex size-12 shrink-0 items-center justify-center text-lg"
		onclick={() => (isOpen = true)}
		aria-label="Open menu"
		bind:this={openEl}><IconBurger /></button
	>
	<div class="flex h-full items-center justify-center overflow-hidden">
		{#if page.params?.id}
			<span class="max-w-full truncate px-4 first-letter:uppercase" data-testid="chat-title"
				>{title}</span
			>
		{/if}
	</div>
	<div class="flex items-center">
		{#if isHuggingChat}
			<button
				type="button"
				class="flex size-8 shrink-0 items-center justify-center text-lg"
				disabled={!canShare}
				onclick={() => {
					if (!canShare) return;
					shareModal.open();
				}}
				aria-label="Share conversation"
			>
				<IconShare classNames={!canShare ? "opacity-40" : ""} />
			</button>
		{/if}
		<a
			href="{base}/"
			class="flex size-8 shrink-0 items-center justify-center text-lg"
			onclick={(e) => {
				if (requireAuthUser()) {
					e.preventDefault();
				}
			}}
		>
			<IconNew />
		</a>
	</div>
</nav>

<!-- Mobile drawer overlay - shows when drawer is open -->
{#if isOpen}
	<button
		type="button"
		class="fixed inset-0 z-20 cursor-default bg-black/30 md:hidden"
		style="opacity: {Math.max(0, Math.min(1, (100 + tween.current) / 100))};"
		onclick={closeDrawer}
		aria-label="Close mobile navigation"
	></button>
{/if}

<nav
	style="transform: translateX({Math.max(
		-100,
		Math.min(0, tween.current)
	)}%); width: {drawerWidthPercentage}%;"
	class:shadow-[5px_0_15px_0_rgba(0,0,0,0.3)]={isOpen}
	class="fixed bottom-0 left-0 top-0 z-30 grid max-h-screen grid-cols-1
	grid-rows-[auto,1fr,auto,auto] rounded-r-xl bg-white pt-4 dark:bg-gray-900 md:hidden"
>
	{@render children?.()}
</nav>
