<template>
	<div
		id="container"
		class="container"
		:class="{ [theme]: true }"
		@click="blur"
	>
		<transition name="slide">
			<Sidebar
				v-if="showSidebar"
				@sidebar="showSidebar = false"
			/>
		</transition>

		<Header />

		<div
			id="content"
			ref="content"
			class="content"
		>
			<p
				v-if="psa.enabled"
				class="psa"
				:class="{ [psa.type]: true }"
				v-html="psa.text"
			/>

			<slot @scroll="scroll" />

			<Footer />
		</div>

		<BottomNavigation
			class="nav"
			@sidebar="showSidebar = true"
		/>

		<div
			ref="feedbackContainer"
			class="feedback-container"
		>
			<div
				v-if="feedback"
				ref="feedbackBubble"
				class="feedback"
				:class="{ [feedback.type]: true }"
			>{{ feedback.message }}</div>
		</div>
	</div>
</template>

<script setup>
import {
	ref,
	onMounted,
	nextTick,
	inject,
} from 'vue';

import events from '#/src/events.js';

import Header from '#/components/header/header.vue';
import Footer from '#/components/footer/footer.vue';
import Sidebar from '#/components/sidebar/sidebar.vue';
import BottomNavigation from '#/components/footer/navigation.vue';

const pageContext = inject('pageContext');
const { psa } = pageContext.env;
const theme = ref(pageContext.env.theme);

const content = ref(null);
const feedback = ref(null);
const feedbackContainer = ref(null);
const feedbackBubble = ref(null);
const showSidebar = ref(false);

function blur() {
	events.emit('blur');
}

onMounted(() => {
	events.on('scrollUp', () => { content.value.scrollTop = 0; });

	events.on('feedback', async (event) => {
		feedback.value = event;

		await nextTick();

		feedbackBubble.value.animate([
			{
				visibility: 'visible',
				transform: 'scaleY(0)',
				opacity: 1,
			},
			{
				transform: 'scaleY(1)',
				opacity: 1,
				offset: 0.002,
			},
			{
				transform: 'scaleY(1)',
				opacity: 1,
				offset: 0.5,
			},
			{
				opacity: 0,
			},
		], {
			duration: event.type === 'error' ? 5000 : 3000,
			easing: 'ease-in-out',
		});
	});

	events.on('theme', (newTheme) => {
		theme.value = newTheme;
	});
});
</script>

<style>
.slide-enter-active,
.slide-leave-active {
	&.sidebar-container {
		transition: background .15s ease-in-out;
	}

	.sidebar {
		transition: transform .15s ease-in-out;
	}
}

.slide-enter-from,
.slide-leave-to {
	&.sidebar-container {
		background: transparent;
	}

	.sidebar {
		transform: translate(100%, 0);
	}
}

.psa {
	padding: .5rem 1rem;
	margin: 0;
	box-shadow: inset 0 0 3px var(--shadow-weak-20);
	background: var(--notice);
	color: var(--text-light);
	text-align: center;
	font-weight: bold;

	&.alert {
		background: var(--warn);
	}

	a {
		color: inherit;
	}
}
</style>

<style scoped>
.container {
	height: 100%;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	background: var(--background);
    color: var(--text);
}

.content {
	display: flex;
	flex-direction: column;
	flex-grow: 1;
	overflow-y: auto;
}

.nav {
	display: none;
}

.feedback-container {
	width: 100%;
	display: flex;
	justify-content: center;
	position: fixed;
	bottom: 2rem;
	z-index: 1000;
	pointer-events: none;
}

.feedback {
	padding: .5rem 1rem;
	margin: 0 .5rem;
	border-radius: 1rem;
	box-shadow: 0 0 3px var(--shadow-weak-10);
	background: var(--grey-dark-40);
	color: var(--text-light);
	font-size: .9rem;
	visibility: hidden;
	line-height: 1.5;

	&.success {
		background: var(--success);
	}

	&.error {
		background: var(--error);
	}

	&.remove,
	&.undo {
		background: var(--warn);
	}
}

@media(--small-10) {
	.nav {
		display: flex;
	}

	.feedback-container {
		bottom: 5rem;
	}
}
</style>