<template>
	<section class="settings-page">
		<div class="settings-page__content">
			<aside class="settings-page__sidebar">
				<div class="settings-page__title">
					Personal Settings
				</div>
				<div
					class="settings-page__highlight"
					:style="highlightStyle"
				/>
				<nuxt-link
					v-for="(tab, i) in settingTabs"
					:key="i"
					:to="tab.path"
					tag="div"
				>
					<div
						class="settings-page__tab"
						role="button"
					>
						<div class="settings-page__tab-highlight" />
						<w-icon xl class="left">
							{{ tab.icon }}
						</w-icon>
						<div>
							<div>
								{{ tab.name }}
							</div>
							<small>
								{{ tab.desc }}
							</small>
						</div>
					</div>
					<w-divider />
				</nuxt-link>
			</aside>
			<div class="settings-page__overview">
				<Container narrow>
					<div class="settings-page__header">
						<VindiAvatar
							:profile="$store.state.profile"
							:size="45"
						/>
						<div class="settings-page__profile-details">
							<h1>
								{{ $store.state.profile.fullName }}
							</h1>
							<p>{{ $t('SETTINGS_PROFILE_DESCRIPTION') }} </p>
						</div>
					</div>
					<section class="settings-page__view">
						<w-button
							v-if="profile.role == 'admin'"
							color="white"
							class="settings-page__manage"
							bg-color="error"
							@click="viewAsAdmin"
						>
							<w-icon class="left">
								mdi mdi-gavel
							</w-icon>
							Manage Account
						</w-button>

						<VindiTitle :icon="currentTab.icon">
							{{ $t(currentTab.name) }}
						</VindiTitle>
						<w-divider />
						<NuxtChild
							:profile="profile"
						/>
					</section>
				</Container>
			</div>
		</div>
		
		<VindiSaveBox
			v-model="profile"
			:on-save="saveSettings"
		/>
	</section>
</template>

<script lang="ts">
import Vue from 'vue';
import { buildPath } from '~/src/helpers';
import fetchSettingsPage from '~/assets/query/settings/fetchSettingsPage.gql';
import updateSettings from '~/assets/query/settings/updateSettings.gql';
import { cloneDeep, pick } from 'lodash';

export default Vue.extend({
	middleware: 'authenticated',
	
	async asyncData(context) {

		// Redirect to first tab if no tab is specified
		if(context.route.matched.length == 1) {
			const tabId = context.$registries.userSettings.getFirst()!.id;
			const path = buildPath(context.route.path, tabId);

			context.redirect(path);
			return;
		}

		// Fetch current user settings
		const result = await context.$api.query(fetchSettingsPage);

		const tabs = context.$registries.userSettings;
		const segments = context.route.matched[1].path.split('/');
		const tabInstance = tabs.get(segments[segments.length - 1]);
		const indicator = tabInstance ? tabs.toArray().indexOf(tabInstance) : 0;

		return {
			profile: result.profile,
			original: cloneDeep(result.profile),
			tabIndicator: indicator,
			currentTab: tabInstance
		};
	},

	data: () => ({
		profile: null as any,
		original: null as any,
		currentTab: null as any,
		tabIndicator: 0
	}),

	computed: {
		settingTabs(): any[] {
			return this.$registries.userSettings.toItems().map(({ content, id }) => ({
				...content,
				name: this.$t(content.name),
				desc: this.$t(content.desc),
				path: `/settings/${id}`,
			}));
		},
		highlightStyle(): any {
			const index = this.tabIndicator;

			return index !== undefined ? {
				top: 52 + (index * 69) + 'px'
			} : {
				display: 'none'
			};
		}
	},

	watch: {
		'$route'() {
			this.updateIndicator();
		}
	},

	methods: {
		
		revertSettings() {
			this.profile = this.original;
		},

		updateIndicator() {
			const tabs = this.$registries.userSettings;
			const segments = this.$route.matched[1].path.split('/');
			const tabInstance = tabs.get(segments[segments.length - 1]);


			if(!tabInstance) {
				this.tabIndicator = 0;
			} else {
				this.currentTab = tabInstance;
				this.tabIndicator = tabs.toArray().indexOf(tabInstance);
			}
		},

		viewAsAdmin() {
			if(this.profile.role == "admin") this.$router.push(`/admin/users/${this.profile.id}/edit`);
		},

		async saveSettings() {
			const avatar = this.profile.avatar;
			const originalAvatar = this.original.avatar;

			if(avatar && avatar != originalAvatar) {
				await this.$api.upload('avatar', avatar as unknown as File);								
			}

			const profile = pick(this.profile, [
				'fullName', 'email', 'username', 'bio', 'location', 'website'
			]);

			await this.$api.query(updateSettings, {
				details: profile
			});

			this.$store.dispatch('updateProfile');

			// this.$waveui.notify({
			// 	message: this.$t('PROJECT_SETTINGS_SAVE_SUCCESS'),
			// 	success: true
			// });
		}
	}
	
});
</script>

<style lang="scss">
.settings-page {

	&__highlight {
		@include transition(all);
		
		background-color: var(--color-primary);
		position: absolute;
		height: 4.25rem;
		width: 0.25rem;
		z-index: 10;
		left: 0;
	}

	&__content {
		flex-direction: column;
		display: flex;

		@include breakpoint(md) {
			flex-direction: row;
		}
	}

	&__overview {
		@include padding(8);
		
		flex-grow: 1;
	}

	&__manage {
		position: absolute;
		right: 15px;
		top: -45px;
	}

	&__view {
		@include shadow;
		@include rounded('3xl');
		@include padding(6);
		@include padding(4, t);
		@include margin(2, t);
		@include margin(20, b);
		
		background-color: var(--color-shade-0);
		min-height: 250px;
		display: flex;
		flex-direction: column;
		position: relative;

		@include dark {
			background-color: var(--color-shade-2);
		}
	}

	&__sidebar {
		@include shadow;
		
		background-color: var(--color-shade-0);
		flex-direction: column;
		position: relative;
		display: flex;

		@include breakpoint(md) {
			height: calc(100vh - $toolbar-height);
			position: sticky;
			top: $toolbar-height;
			width: 18rem;
		}

		@include breakpoint(lg) {
			width: 24rem;
		}

		.w-divider {
			margin: 0;

			@include dark {
				border-color: #272727;
			}
		}
	}

	&__title {
		@include padding(4, x);
		@include font-size(lg);
		@include font-weight(semibold);

		// Nonstandard padding used to align with
		// the height of a single sidebar item.
		@include padding(3.5, y);

		background-color: var(--color-primary);
		color: white;
	}

	&__header {
		@include padding(8, y);

		display: flex;
		align-items: center;
		justify-content: center;

		h1 {
			@include font-size('3xl');

			display: block;
		}
	}

	&__profile-details {
		@include padding(5, l);
	}

	&__tab {
		@include transition(colors);
		@include padding(3);
		@include padding(4, l);

		user-select: none;
		cursor: pointer;
		display: flex;
		align-items: center;
		position: relative;

		.w-icon {
			@include margin(4, r);
		}

		&:hover {
			background-color: var(--color-misc-2);
		}

		> div {
			@include truncate;
		}

		small {
			@include truncate;
		}
	}

	.nuxt-link-active &__tab {
		background-color: unset;
	}

	&__tab-highlight {
		@include transition(opacity);
		
		background-color: var(--color-primary);
		position: absolute;
		z-index: -1;
		opacity: 0;
		inset: 0;

		.nuxt-link-active & {
			opacity: 0.1;
		}
	}
	
}
</style>