<template>
	<div class="label-selector">
		<div
			v-if="isLoading"
			class="label-selector__loading"
		>
			<w-progress
				color="primary"
				size="2.5em"
				circle
			/>
		</div>
		<template v-else>
			<w-input
				ref="filter"
				v-model="filterQuery"
				bg-color="shade-3"
				placeholder="Search labels..."
				class="label-selector__input"
				inner-icon-left="mdi mdi-magnify"
				autocomplete="off"
				color="grey"
			/>

			<w-divider />

			<div class="simple-subtitle">
				Primary Labels
			</div>

			<div
				v-if="!primaryLabelsFiltered.length"
				class="label-selector__empty"
			>
				No results found!
			</div>

			<div class="label-selector__list">
				<div
					v-for="label in primaryLabelsFiltered"
					:key="label.id"
					class="label-selector__label"
					:class="computeLabelClass(label)"
					@click="toggleLabel(label)"
				>
					<TaskLabel :value="label">
						<w-icon v-if="isAssigned(label)">
							mdi mdi-check
						</w-icon>
					</TaskLabel>
				</div>
			</div>

			<w-divider />

			<div class="simple-subtitle">
				Secondary Labels
			</div>

			<div
				v-if="!secondaryLabelsFiltered.length"
				class="label-selector__empty"
			>
				No results found!
			</div>

			<div class="label-selector__list">
				<div
					v-for="label in secondaryLabelsFiltered"
					:key="label.id"
					class="label-selector__label"
					:class="computeLabelClass(label)"
					@click="toggleLabel(label)"
				>
					<TaskLabel :value="label">
						<w-icon v-if="isAssigned(label)">
							mdi mdi-check
						</w-icon>
					</TaskLabel>
				</div>
			</div>

			<w-divider />

			<div class="simple-subtitle">
				Tag Labels
			</div>

			<div
				v-if="!tagLabelsFiltered.length"
				class="label-selector__empty"
			>
				No results found!
			</div>

			<div class="label-selector__list">
				<div
					v-for="label in tagLabelsFiltered"
					:key="label.id"
					class="label-selector__label"
					:class="computeLabelClass(label)"
					@click="toggleLabel(label)"
				>
					<TaskLabel :value="label">
						<w-icon v-if="isAssigned(label)">
							mdi mdi-check
						</w-icon>
					</TaskLabel>
				</div>
			</div>
		</template>
	</div>
</template>

<script lang="ts">
import Vue, { PropType } from 'vue';
import labelSelector from '~/assets/query/viewer/labelSelector.gql';
import { focusInput } from '~/src/helpers';

export default Vue.extend({
	props: {
		labels: {
			required: true,
			type: Array as PropType<any[]>
		},
		projectId: {
			required: true,
			type: Number
		}
	},

	data: () => ({
		isLoading: true,
		filterQuery: '',
		allLabels: [] as any[]
	}),

	computed: {
		primaryLabel(): any {
			return this.labels.find(label => label.type == 'PRIMARY');
		},
		labelsFiltered(): any[] {
			const query = this.filterQuery.toLowerCase();

			return this.allLabels.filter(label => {
				return (
					label.title.toLowerCase().includes(query)
				);
			});
		},
		primaryLabelsFiltered(): any[] {
			return this.labelsFiltered.filter(label => label.type == 'PRIMARY');
		},
		secondaryLabelsFiltered(): any[] {
			return this.labelsFiltered.filter(label => label.type == 'SECONDARY');
		},
		tagLabelsFiltered(): any[] {
			return this.labelsFiltered.filter(label => label.type == 'TAG');
		}
	},

	mounted() {
		this.fetchProjectLabels();	
	},

	methods: {
		async fetchProjectLabels() {
			this.isLoading = true;

			const result = await this.$api.query(labelSelector, {
				projectId: this.projectId
			});

			this.allLabels = result.project.labels;
			this.isLoading = false;

			this.$nextTick(() => {
				focusInput(this.$refs.filter as any);
			});
		},

		computeLabelClass(label: any) {
			return {
				'label-selector__label--available': !this.isAssigned(label)
			};
		},

		isAssigned(label: any): boolean {
			return this.labels.includes(label.id);
		},

		toggleLabel(label: any) {
			if(this.labels.includes(label.id)) {
				this.$emit('remove', label);
			} else {
				if(label.type == 'PRIMARY') {
					this.deselectPrimary();
				}

				this.$emit('add', label);
			}
		},

		deselectPrimary() {
			for(const label of this.primaryLabelsFiltered) {
				if(this.labels.includes(label.id)) {
					this.$emit('remove', label);
				}
			}
		}
	}
});
</script>

<style lang="scss">
.label-selector {
	@include padding(3);

	width: 18rem;

	&__loading {
		@include padding(3, y);

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

	&__list {
		@include margin(4, b);
	}

	&__empty {
		@include rounded(md);
		@include padding(3);

		text-align: center;
		color: var(--color-negative-4);
		background-color: var(--color-shade-2);
	}

	&__label {
		@include transition(all);
		@include margin(1, b);

		cursor: pointer;

		&--available {
			@include margin(3, l);

			opacity: 0.6;
		}
	}
}
</style>