<script lang="ts" module>
export let menu_is_open = writable(true)
</script>
<script lang="ts">
import { highlight_current_page } from "lib/HighlightCurrentPage";
import { user } from "lib/UserStore";
import Euro from "util/Euro.svelte";
import { formatDataVolume } from "util/Formatting";
import Router from "wrap/Router.svelte";
import Bookmarks from "./Bookmarks.svelte";
import { onMount } from "svelte";
import { fs_get_node } from "lib/FilesystemAPI";
import { css_from_path } from "filesystem/edit_window/Branding";
import { loading_run, loading_store } from "lib/Loading";
import Spinner from "util/Spinner.svelte";
import { get_user } from "lib/NovaAPI";
import Tree from "./Tree.svelte";
import MenuEntry from "./MenuEntry.svelte";
import { writable } from "svelte/store";
import { breadcrumbs_store } from "./BreadcrumbStore";

// The menu swipe will be detected if it was less than this much pixels from the
// screen edge
const screen_edge_offset = 40

// Dead zone before the swipe action gets detected
const swipe_dead_zone = screen_edge_offset/4

// If the screen is less wide than this, the menu will appear full screen
const min_screen_size_fullscreen_menu = 500

// If the screen is smaller than this the menu will be closed by default
const min_screen_size_menu_open = 800

onMount(async () => {
	if (document.documentElement.clientWidth < min_screen_size_menu_open) {
		menu_close()
	}

	await loading_run(async () => {
		const user = await get_user()
		if (user.username === undefined || user.username === "") {
			return
		}
		const root = await fs_get_node("/me")
		document.documentElement.style = css_from_path(root.path)
	})
})

let menu: HTMLDivElement
let nav: HTMLElement
let dragging: boolean = false
let start_x: number
let start_y: number
let render_offset: number
let initial_offset: number
const touchstart = (e: TouchEvent) => {
	start_x = e.touches[0].clientX
	start_y = e.touches[0].clientY
	const rect = menu.getBoundingClientRect()
	if (start_x < Math.max(screen_edge_offset, (rect.width+rect.left))) {
		dragging = true
		e.stopPropagation()
	}

	render_offset = rect.left
	initial_offset = rect.left
}

const touchmove = (e: TouchEvent) => {
	if (!dragging) {
		return
	}

	const x = e.touches[0].clientX - start_x
	const y = e.touches[0].clientY - start_y
	const abs_x = Math.abs(x)
	const abs_y = Math.abs(y)

	// The cursor must have moved at least swipe_dead_zone pixels and twice as
	// much on the x axis than the y axis for it to count as a swipe
	if (abs_x > swipe_dead_zone) {
		if (abs_x > abs_y) {
			e.preventDefault()
			e.stopPropagation()
			set_offset(initial_offset+(x*2))
		} else {
			touchend(e)
		}
	}
}

const touchend = (e: TouchEvent) => {
	if (!dragging) {
		return
	}
	dragging = false

	const menu_width = menu.getBoundingClientRect().width
	if (render_offset > -(menu_width/2)) {
		menu_open()
	} else {
		menu_close()
	}
}

const toggle_menu = (e: MouseEvent) => {
	if (menu.style.transform === "") {
		menu_close()
	} else {
		menu_open()
	}
}
const menu_open = () => {
	set_offset(0)
	menu_is_open.set(true)
	if (document.documentElement.clientWidth < min_screen_size_fullscreen_menu) {
		menu.style.position = "fixed"
		menu.style.width = "100%"
		nav.style.width = "100%"
		nav.style.maxWidth = "100%"
	} else {
		menu.style.position = "relative"
		menu.style.width = ""
		nav.style.width = ""
		nav.style.maxWidth = ""
	}
}
const menu_close = () => {
	set_offset(-menu.getBoundingClientRect().width)
	menu_is_open.set(false)
	menu.style.position = "fixed"

	if (document.documentElement.clientWidth >= min_screen_size_fullscreen_menu) {
		menu.style.width = ""
		nav.style.width = ""
		nav.style.maxWidth = ""
	}
}

const set_offset = (off: number) => {
	render_offset = off

	if (off > -swipe_dead_zone) {
		// Clear the transformation if the offset is zero
		menu.style.transform = ""
	} else {
		menu.style.transform = "translateX(" + off + "px)"
	}
}
</script>

<svelte:window ontouchstart={touchstart} ontouchmove={touchmove} ontouchend={touchend}/>

<div class="wrap">
	<div class="nav_container" bind:this={menu}>
		<div class="scroll_container">
			<nav class="nav bubble" bind:this={nav}>
				{#if document.documentElement.clientWidth < min_screen_size_menu_open}
					<button class="button" onclick={toggle_menu}>
						<i class="icon">menu</i>
						Menu
					</button>
				{/if}

				<a class="button" style="flex: 1 1 auto;" href="/" use:highlight_current_page>
					<span style="flex: 1 1 auto;">Nova.storage</span>
					<img src="/res/img/nova_64.png" style="width: 1.5em; height: 1.5em; flex: 0 0 auto;" alt="Nova.storage logo">
				</a>

				{#if $user !== null}
					<MenuEntry id="subscription_info" collapsed={false}>
						{#snippet title()}
							<div class="username">{$user.username}</div>
						{/snippet}

						{#snippet body()}
							<div class="stats_table">
								<div>Subscription</div>
								<div>{$user.subscription.name}</div>

								{#if $user.subscription.type === "prepaid"}
									<div>Credit</div>
									<div><Euro amount={$user.balance_micro_eur}/></div>
								{/if}

								<div>Storage used</div>
								<div>{formatDataVolume($user.filesystem_storage_used, 3)}</div>
								<div>Transfer used</div>
								<div>{formatDataVolume($user.monthly_transfer_used, 3)}</div>
							</div>
						{/snippet}
					</MenuEntry>

					<a class="button" href="/user" use:highlight_current_page>
						<i class="icon">person</i>
						<span>Account</span>
					</a>
					<a class="button" href="/d/me" use:highlight_current_page>
						<i class="icon">folder</i>
						<span>Filesystem</span>
					</a>
					<a class="button" href="/d/me/.Trash" use:highlight_current_page>
						<i class="icon">delete</i>
						<span>Trash</span>
					</a>
					{#if $user.is_admin}
						<a class="button" href="/admin" use:highlight_current_page>
							<i class="icon">admin_panel_settings</i>
							<span>Admin Panel</span>
						</a>
					{/if}
				{:else}
					<a class="button" href="/login" use:highlight_current_page>
						<i class="icon">login</i>
						<span>Login</span>
					</a>
					<a class="button" href="/register" use:highlight_current_page>
						<i class="icon">how_to_reg</i>
						<span>Register</span>
					</a>
				{/if}

				<MenuEntry id="other_pages" collapsed={false}>
					{#snippet title()}
						<span style="flex: 1 1 auto;">
							<span style="flex: 1 1 auto;">Other pages</span>
						</span>
					{/snippet}
					{#snippet body()}
						<a class="button" href="/speedtest" use:highlight_current_page>
							<i class="icon">speed</i>
							<span>Speedtest</span>
						</a>
						<a class="button" href="/appearance" use:highlight_current_page>
							<i class="icon">palette</i>
							<span>Themes</span>
						</a>
					{/snippet}
				</MenuEntry>

				<Bookmarks/>
				<Tree/>
			</nav>
		</div>
	</div>

	<div class="page">
		<div class="header bubble">
			<button class="menu_button" onclick={toggle_menu}>
				<i class="icon">menu</i>
			</button>

			<div class="breadcrumbs">
				{#if $breadcrumbs_store !== null}
					{@render $breadcrumbs_store()}
				{/if}
			</div>
		</div>

		<Router/>
	</div>

	{#if $loading_store !== 0}
		<div class="spinner">
			<Spinner/>
		</div>
	{/if}

</div>

<style>
.wrap {
	display: flex;
	flex-direction: row;

	color: var(--body_text_color);
	background-image: var(--background_image);
	background-color: var(--background_color);
	background-size: var(--background_image_size, initial);
	background-position: var(--background_image_position, initial);
	background-repeat: var(--background_image_repeat, repeat);
	background-attachment: fixed;
	width: 100%;
	min-height: 100vh;
}
.nav_container {
	flex: 0 0 auto;
	backdrop-filter: blur(3px);
	z-index: 9;
}
.scroll_container {
	position: sticky;
	top: 0;
	overflow-x: hidden;
	overflow-y: auto;
	max-height: 100vh;
	height: 100vh;
	padding: 4px;
	scrollbar-gutter: stable;
}
.nav {
	display: flex;
	flex-direction: column;
	width: 15em;
	margin: 0;
	padding: 4px;
}
.button {
	background: none;
	box-shadow: none;
}
.page {
	flex: 1 1 auto;
	max-width: 100vw;
	min-width: 0; /* prevents overflow */
	display: flex;
	flex-direction: column;
}
.username {
	flex: 1 1 auto;
	margin: 3px;
}

.stats_table {
	display: grid;
	grid-template-columns: auto auto;
	gap: 0.2em 1em;
	margin: 5px;
}

.header {
	flex: 0 0 auto;
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: left;
	backdrop-filter: blur(3px);
	position: sticky;
	top: 4px;
	z-index: 8; /* below navigation, on top of most other things */
}
.menu_button {
	flex: 0 0 auto;
	background: none;
	box-shadow: none;
}
.breadcrumbs {
	flex: 1 1 auto;
	display: flex;
	flex-wrap: wrap;
	flex-direction: row;
	align-items: center;
	overflow-x: hidden;
}

.spinner {
	position: fixed;
	top: 10px;
	right: 10px;
	height: 120px;
	width: 120px;
	z-index: 11; /* One above the menu */
}
</style>
