<template>
	<div class="task-tile" @click="openTask">
		<div class="task-tile__cover">
			<img 
				v-if="task.bannerImage"
				:src="task.bannerImage.filePath"
				class="task-tile__cover"
			>
		</div>
		<div class="task-tile__content">
			<w-flex>
				<div>
					<span class="task-tile__id">
						#{{ task.localId }}
					</span>
					{{ task.summary }}
				</div>
				<VindiSpacer />
				<w-icon
					v-if="primaryLabel"
					class="task-tile__icon"
					:style="{ color: primaryLabel.color }"
					:title="primaryLabel.title"
					xl
				>
					{{ primaryLabel.icon }}
				</w-icon>
			</w-flex>
			<div
				v-show="task.labels.length"
				ref="labels"
				class="task-tile__labels"
				@wheel="scrollLabels"
			>
				<div
					v-for="(label, i) in displayLabels"
					:key="i"
					:style="computeLabelStyle(label, i)"
					:title="label.title"
					class="task-tile__label"
					@click.stop="toggleLabelNames"
				>
					{{ $store.state.showLabelNames ? label.title : '' }}
				</div>
			</div>
			<VindiSpacer />
			<w-flex align-center>
				<IgnoreText class="task-tile__status">
					
					<!-- Start time -->
					<span
						v-if="task.startTime"
						title="Task has start date"
					>
						<w-icon>
							mdi mdi-calendar
						</w-icon>
						{{ formatCalendarDate(task.startTime) }}
					</span>

					<!-- End time -->
					<span
						v-if="task.endTime"
						title="Task has due date"
					>
						<w-icon>
							mdi mdi-clock-outline
						</w-icon>
						{{ formatCalendarDate(task.endTime) }}
					</span>

					<!-- Description -->
					<w-icon
						v-if="task.description"
						title="Task has a description"
					>
						mdi mdi-text
					</w-icon>

					<!-- Attachments -->
					<span
						v-if="task.attachments.length"
						title="Task has attachments"
					>
						<w-icon rotate45a>
							mdi mdi-attachment
						</w-icon>
						{{ task.attachments.length }}
					</span>

					<!-- Parent task -->
					<w-icon
						v-if="task.parentTask"
						title="Task has a parent"
					>
						mdi mdi-subdirectory-arrow-right
					</w-icon>

					<!-- Pinned -->
					<w-icon
						v-if="task.isPinned"
						title="Task is pinned"
					>
						mdi mdi-pin
					</w-icon>
				</IgnoreText>
				<VindiSpacer />
				<VindiAvatar
					v-for="(member, i) in task.assignees"
					:key="i"
					:size="28"
					:profile="member"
					:open-profile="false"
					:show-border="false"
					class="task-tile__assignee"
				/>
			</w-flex>
		</div>
	</div>
</template>

<script lang="ts">
import dayjs from 'dayjs';
import Vue from 'vue';
import { expectProp, isColorDark } from '../../src/helpers';

export default Vue.extend({
	name: 'TaskTile',

	props: {
		task: {
			type: Object,
			required: true,
			validator: expectProp([
				'id',
				'labels',
				'localId',
				'summary',
				'isWatching',
				'assignees',
				'childTasks',
				'description',
				'bannerImage'
			])
		}
	},

	computed: {
		primaryLabel(): any {
			return this.task.labels.find((label: any) => label.type == 'PRIMARY');
		},
		displayLabels(): any[] {
			return this.task.labels.filter((label: any) => label.type != 'TAG');
		}
	},

	methods: {
		openTask() {
			this.$store.dispatch('openTaskViewer', this.task.id);
		},

		computeLabelStyle(label: any, index: number): any {
			const style: any = {
				backgroundColor: label.color,
				color: '#000'
			};

			// Find the clip sides
			const clipRight = index < this.displayLabels.length - 1;
			const clipLeft = index > 0;

			// Apply clip path
			if(clipLeft && clipRight) {
				style.clipPath = 'polygon(6px 0, 100% 0, calc(100% - 6px) 100%, 0 100%)';
			} else if(clipLeft) {
				style.clipPath = 'polygon(6px 0, 100% 0, 100% 100%, 0 100%)';
			} else if(clipRight) {
				style.clipPath = 'polygon(0 0, 100% 0, calc(100% - 6px) 100%, 0% 100%)';
			}

			// Apply fitting border radius
			if(clipLeft) {
				style.borderBottomLeftRadius = 0;
				style.borderTopLeftRadius = 0;
			}
			
			if(clipRight) {
				style.borderBottomRightRadius = 0;
				style.borderTopRightRadius = 0;
			}

			// Apply most suitable text color
			if(label.color) {
				style.color = isColorDark(label.color) ? '#fff' : '#000';
			}

			return style;
		},

		toggleLabelNames() {
			this.$store.commit('setShowLabelNames', !this.$store.state.showLabelNames);
		},

		scrollLabels(e: any) {
			const el = this.$refs.labels as any;

			el.scrollLeft += e.deltaY * -0.2;
		},

		formatCalendarDate(time: string) {
			const date = dayjs(parseInt(time));
			const format = this.$t('SHORT_DATE_FORMAT') as string;

			return date.format(format);
		},
	}
});
</script>

<style lang="scss">
.task-tile {
	@include rounded(lg);
	cursor: pointer;
	user-select: none;

	background-color: var(--color-shade-0);
	box-shadow: rgb(0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px;

	@include dark {
		background-color: var(--color-negative-1);
		color: black;
	}

	&__content {
		@include font-size(sm);
		@include padding(3);

		overflow: hidden;
		display: flex;
		flex-direction: column;
		position: relative;
	}

	&__cover {
		@include rounded(lg, t);

		width: 100%;
		height: auto;
	}

	&--ghost {
		box-shadow: unset;
		background-color: rgba(0, 0, 0, 0.05);

		@include dark {
			background-color: rgba(255, 255, 255, 0.15);
		}

		* {
			visibility: hidden;
		}
	}

	> .w-flex {
		flex-grow: 0;
	}

	&__id {
		@include font-weight(bold);
		@include padding(1, r);
	}

	&__icon {
		@include margin(1.5, l);	
	}

	&__labels {
		@include margin(1.5, t);

		overflow-x: hidden;
		white-space: nowrap;
		display: flex;
	}

	&__label {
		@include font-size(xs);
		// @include margin(0.5, y);
		@include padding(0.5, y);
		@include padding(2.5, x);
		@include rounded(full);

		min-height: 9px;
		min-width: 45px;
		background-color: #d0d4dd;
		text-align: center;
		flex-shrink: 0;
	}

	&__assignee {
		@include rounded(full);
		
		border: 2px solid var(--color-shade-0);
		
		&:not(:last-child) {
			margin-right: -8px;
		}
	}

	&__status {
		@include margin(2.5, t);
		@include font-weight(light);
		
		display: flex;
		color: #b1b1b1;
		gap: 0.5rem;

		@include dark {
			color: #929292;
		}

		&:empty {
			display: none;
		}
	}
}
</style>