<template>
	<aside :class="{'is-active': menuActive}" class="namespace-container">
		<nav class="menu">
			<router-link :to="{name: 'home'}" class="logo">
				<Logo width="164" height="48"/>
			</router-link>
			<ul class="menu-list">
				<li
					v-for="({title, to, shortcut, icon, }, index) in MAIN_NAV_ITEMS"
					:key="index"
				>
					<router-link :to="to" v-shortcut="shortcut">
						<icon class="icon" :icon="icon"/>
						{{ title }}
					</router-link>
				</li>
			</ul>
		</nav>

		<LoadingIndicator
			class="namespaces-lists"
			:isLoading="loading"
			element="nav"
		>
			<NavigationNamespace
				v-for="(n, nk) in namespaces"
				:key="n.id"
				:namespace="n"
				:title="namespaceTitles[nk]"
				:showList="listsVisible[n.id] ?? true"
			/>
		</LoadingIndicator>
		<PoweredByLink class="navigation__powered-by-link " />
	</aside>
</template>

<script setup lang="ts">
import {ref, computed, onBeforeMount} from 'vue'
import {useStore} from 'vuex'
import {useEventListener} from '@vueuse/core'
import {useI18n} from 'vue-i18n'

import Logo from '@/components/home/Logo.vue'
import PoweredByLink from '@/components/home/PoweredByLink.vue'
import NavigationNamespace from './NavigationNamespace.vue'

import {MENU_ACTIVE} from '@/store/mutation-types'
import {getNamespaceTitle} from '@/helpers/getNamespaceTitle'
import NamespaceModel from '@/models/namespace'

const {t} = useI18n()

const MAIN_NAV_ITEMS = [
	{
		title: t('navigation.overview'),
		icon: 'calendar',
		to: { name: 'home'},
		shortcut: 'g o',
	},
	{
		title: t('navigation.upcoming'),
		icon: ['far', 'calendar-alt'],
		to: { name: 'tasks.range'},
		shortcut: 'g u',
	},
	{
		title: t('namespace.title'),
		icon: 'layer-group',
		to: { name: 'namespaces.index'},
		shortcut: 'g n',
	},
	{
		title: t('label.title'),
		icon: 'tags',
		to: { name: 'labels.index'},
		shortcut: 'g a',
	},
	{
		title: t('team.title'),
		icon: 'users',
		to: { name: 'teams.index'},
		shortcut: 'g m',
	},
]

const store = useStore()

const menuActive = computed(() => store.state.menuActive)
const loading = computed(() => store.state.loading && store.state.loadingModule === 'namespaces')


const namespaces = computed(() => {
	return (store.state.namespaces.namespaces as NamespaceModel[]).filter(n => !n.isArchived)
})
const activeLists = computed(() => {
	return namespaces.value.map(({lists}) => {
		return lists?.filter(item => {
			return typeof item !== 'undefined' && !item.isArchived
		})
	})
})

const namespaceTitles = computed(() => {
	return namespaces.value.map((namespace) => getNamespaceTitle(namespace))
})

const namespaceListsCount = computed(() => {
	return namespaces.value.map((_, index) => activeLists.value[index]?.length ?? 0)
})


function resize() {
	// Hide the menu by default on mobile
	store.commit(MENU_ACTIVE, window.innerWidth >= 770)
}

useEventListener('resize', resize)
resize()



function toggleLists(namespaceId: number) {
	listsVisible.value[namespaceId] = !listsVisible.value[namespaceId]
}

const listsVisible = ref<{ [id: NamespaceModel['id']]: boolean }>({})
// FIXME: async action will be unfinished when component mounts
onBeforeMount(async () => {
	const namespaces = await store.dispatch('namespaces/loadNamespaces') as NamespaceModel[]
	namespaces.forEach(n => {
		if (typeof listsVisible.value[n.id] === 'undefined') {
			listsVisible.value[n.id] = true
		}
	})
})
</script>

<style lang="scss" scoped>
$navbar-padding: 2rem;
$vikunja-nav-background: var(--site-background);
$vikunja-nav-color: var(--grey-700);
$vikunja-nav-selected-width: 0.4rem;

.navigation {
	position: fixed;
	top: $navbar-height;
	bottom: 0;
	left: 0;
	transition: transform $transition-duration ease-in;
	transform: translateX(-100%);
	overflow-x: auto;
	width: $navbar-width;

	@media screen and (max-width: $tablet) {
		top: 0;
		width: 70vw;
		z-index: 20;
	}

	&.is-active {
		transform: translateX(0);
		transition: transform $transition-duration ease-out;
	}
}

.navigation {
	background: $vikunja-nav-background;
	color: $vikunja-nav-color;
	display: flex;
	flex-direction: column;


	.menu {


		.menu-label,
		.menu-list span.list-menu-link,
		.menu-list a {
			display: flex;
			align-items: center;
			justify-content: space-between;
			cursor: pointer;



			&:hover .favorite {
				opacity: 1;
			}

			&:hover {
				background: transparent;
			}
		}

		.list-menu-title {
			overflow: hidden;
			text-overflow: ellipsis;
			width: 100%;
		}

		.color-bubble {
			height: 12px;
			flex: 0 0 12px;
		}

		.favorite {
			margin-left: .25rem;
			transition: opacity $transition, color $transition;
			opacity: 0;

			&:hover {
				color: var(--warning);
			}

			&.is-favorite {
				opacity: 1;
				color: var(--warning);
			}
		}

		.menu-label {
			.color-bubble {
				width: 14px;
				height: 14px;
				flex-basis: auto;
			}

			.is-archived {
				min-width: 85px;
			}
		}





		.menu-list {
			li {
				height: 44px;
				display: flex;
				align-items: center;

				&:hover {
					background: var(--white);
				}

				:deep(.dropdown-trigger) {
					opacity: 0;
					padding: .5rem;
					cursor: pointer;
					transition: $transition;
				}

				&:hover :deep(.dropdown-trigger) {
					opacity: 1;
				}
			}

			.flip-list-move {
				transition: transform $transition-duration;
			}

			.ghost {
				background: var(--grey-200);

				* {
					opacity: 0;
				}
			}

			span.list-menu-link, li > a {
				padding: 0.75rem .5rem 0.75rem ($navbar-padding * 1.5 - 1.75rem);
				transition: all 0.2s ease;

				border-radius: 0;
				white-space: nowrap;
				text-overflow: ellipsis;
				overflow: hidden;
				width: 100%;
				border-left: $vikunja-nav-selected-width solid transparent;

				.icon {
					height: 1rem;
					vertical-align: middle;
					padding-right: 0.5rem;

					&.handle {
						opacity: 0;
						transition: opacity $transition;
						margin-right: .25rem;
						cursor: grab;
					}
				}

				&:hover .icon.handle {
					opacity: 1;
				}

				&.router-link-exact-active {
					color: var(--primary);
					border-left: $vikunja-nav-selected-width solid var(--primary);

					.icon {
						color: var(--primary);
					}
				}

				&:hover {
					border-left: $vikunja-nav-selected-width solid var(--primary);
				}
			}
		}



		&.namespaces-lists {
			padding-top: math.div($navbar-padding, 2);
		}

		.icon {
			color: var(--grey-400) !important;
		}
	}

		.logo {
			display: block;

			padding-left: 2rem;
			margin-right: 1rem;

			@media screen and (min-width: $tablet) {
				display: none;
			}
		}

	.top-menu {
		margin-top: math.div($navbar-padding, 2);

		.menu-list {
			li {
				font-weight: 500;
				font-family: $vikunja-font;
			}

			span.list-menu-link, li > a {
				padding-left: 2rem;
				display: inline-block;

				.icon {
					padding-bottom: .25rem;
				}
			}
		}
	}
}

.list-setting-spacer {
	width: 2.5rem;
	flex-shrink: 0;
}

.namespaces-list.loader-container.is-loading {
	min-height: calc(100vh - #{$navbar-height + 1.5rem + 1rem + 1.5rem});
}

a.dropdown-item:hover {
	background: var(--dropdown-item-hover-background-color) !important;
}

.navigation__powered-by-link {
	margin-top: auto;
	color: var(--grey-300);
	text-align: center;
	display: block;
	padding-top: 1rem;
	padding-bottom: 1rem;
	font-size: .8rem;
}
</style>
