<template>
	<section class="project-settings">
		<main class="project-settings__content">
			<aside class="project-settings__sidebar">
				<div
					class="project-settings__title"
					:style="{ backgroundColor: project.accentColor }"
				>
					{{ $t('PROJECT_SETTINGS_TITLE') }}
				</div>
				<div
					class="project-settings__highlight"
					:style="highlightStyle"
				/>
				<nuxt-link
					v-for="(tab, i) in settingTabs"
					:key="i"
					:to="tab.path"
					tag="div"
				>
					<div
						class="project-settings__tab"
						role="button"
					>
						<div
							class="project-settings__tab-highlight"
							:style="{ backgroundColor: project.accentColor }"
						/>
						<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="project-settings__overview">
				<Container narrow>
					<section class="project-settings__view">
						<VindiTitle :icon="currentTab.icon">
							{{ $t(currentTab.name) }}
						</VindiTitle>
						<w-divider />
						<NuxtChild
							:project="project"
						/>
					</section>
				</Container>
			</div>
		</main>
		<VindiSaveBox
			v-model="project"
			:on-save="saveSettings"
		/>
	</section>
</template>

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

export default Vue.extend({
	
	async asyncData(context) {

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

			context.redirect(path);
			return;
		}

		const result = await context.$api.query(fetchSettingsPage, {
			pid: parseSlug(context.params.pid)
		});

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

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

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

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

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

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

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

		updateIndicator() {
			const tabs = this.$registries.projectSettings;
			const segments = this.$route.matched[2].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);
			}
		},

		async saveSettings() {
			const isCoverChanged = this.project.coverImage != this.original.coverImage;

			// Update the cover image
			if(this.project.coverImage != null && isCoverChanged) {
				await this.$api.upload(`cover?project=${this.project.id}`, this.project.coverImage!);
			}

			await this.$api.query(updateSettings, {
				id: this.project.id,
				details: {
					name: this.project.name,
					description: this.project.description || '',
					accentColor: this.project.accentColor,
					isPublic: this.project.isPublic,
					removeCover: (this.project.coverImage == null),
					kanbanColor: this.project.kanbanColor,
					defaultView: this.project.defaultView,
					readme: this.project.readme || ''
				}
			});

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

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

	&__highlight {
		@include transition(all);

		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;
	}

	&__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;

		@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);

		color: white;
	}

	&__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);
		
		position: absolute;
		z-index: -1;
		opacity: 0;
		inset: 0;

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