<template>
	<router-link
		:class="{
			'has-light-text': !colorIsDark(project.hexColor) || background !== null,
			'has-background': blurHashUrl !== '' || background !== null,
		}"
		:style="{
			'background-color': project.hexColor,
			'background-image': blurHashUrl !== null ? `url(${blurHashUrl})` : false,
		}"
		:to="{ name: 'project.index', params: { projectId: project.id} }"
		class="project-card"
		v-if="project !== null && (showArchived ? true : !project.isArchived)"
	>
		<div
			class="project-background background-fade-in"
			:class="{'is-visible': background}"
			:style="{'background-image': background !== null ? `url(${background})` : undefined}"
		/>
		<div class="project-content">
			<span class="is-archived" v-if="project.isArchived">
				{{ $t('namespace.archived') }}
			</span>
			<BaseButton
				v-else
				:class="{'is-favorite': project.isFavorite}"
				@click.stop="projectStore.toggleProjectFavorite(project)"
				class="favorite"
			>
				<icon :icon="project.isFavorite ? 'star' : ['far', 'star']"/>
			</BaseButton>

			<div class="title">{{ project.title }}</div>
		</div>
	</router-link>
</template>

<script lang="ts" setup>
import {type PropType, ref, watch} from 'vue'

import ProjectService from '@/services/project'
import {getBlobFromBlurHash} from '@/helpers/getBlobFromBlurHash'

import {colorIsDark} from '@/helpers/color/colorIsDark'

import BaseButton from '@/components/base/BaseButton.vue'
import type {IProject} from '@/modelTypes/IProject'
import {useProjectStore} from '@/stores/projects'

const background = ref<string | null>(null)
const backgroundLoading = ref(false)
const blurHashUrl = ref('')

const props = defineProps({
	project: {
		type: Object as PropType<IProject>,
		required: true,
	},
	showArchived: {
		default: false,
		type: Boolean,
	},
})

watch(props.project, loadBackground, {immediate: true})

async function loadBackground() {
	if (props.project === null || !props.project.backgroundInformation || backgroundLoading.value) {
		return
	}

	const blurHash = await getBlobFromBlurHash(props.project.backgroundBlurHash)
	if (blurHash) {
		blurHashUrl.value = window.URL.createObjectURL(blurHash)
	}

	backgroundLoading.value = true

	const projectService = new ProjectService()
	try {
		background.value = await projectService.background(props.project)
	} finally {
		backgroundLoading.value = false
	}
}

const projectStore = useProjectStore()
</script>

<style lang="scss" scoped>
.project-card {
	cursor: pointer;
	width: calc((100% - #{($projects-per-row - 1) * 1rem}) / #{$projects-per-row});
	height: $project-height;
	background: var(--white);
	margin: 0 $project-spacing $project-spacing 0;
	border-radius: $radius;
	box-shadow: var(--shadow-sm);
	transition: box-shadow $transition;
	position: relative;
	overflow: hidden;

	&.has-light-text .title {
		color: var(--grey-100) !important;
	}

	&.has-background,
	.project-background {
		background-size: cover;
		background-repeat: no-repeat;
		background-position: center;
	}

	&.has-background .title {
		text-shadow: 0 0 10px var(--black), 1px 1px 5px var(--grey-700), -1px -1px 5px var(--grey-700);
		color: var(--white);
	}

	.project-background {
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
	}

	&:hover {
		box-shadow: var(--shadow-md);
	}

	&:active,
	&:focus,
	&:focus:not(:active) {
		box-shadow: var(--shadow-xs) !important;
	}

	@media screen and (min-width: $widescreen) {
		&:nth-child(#{$projects-per-row}n) {
			margin-right: 0;
		}
	}

	@media screen and (max-width: $widescreen) and (min-width: $tablet) {
		$projects-per-row: 3;
		& {
			width: calc((100% - #{($projects-per-row - 1) * 1rem}) / #{$projects-per-row});
		}

		&:nth-child(#{$projects-per-row}n) {
			margin-right: 0;
		}
	}

	@media screen and (max-width: $tablet) {
		$projects-per-row: 2;
		& {
			width: calc((100% - #{($projects-per-row - 1) * 1rem}) / #{$projects-per-row});
		}

		&:nth-child(#{$projects-per-row}n) {
			margin-right: 0;
		}
	}

	@media screen and (max-width: $mobile) {
		$projects-per-row: 1;
		& {
			width: 100%;
			margin-right: 0;
		}
	}

	.project-content {
		display: flex;
		align-content: space-between;
		flex-wrap: wrap;
		padding: 1rem;
		position: absolute;
		height: 100%;
		width: 100%;


		.is-archived {
			font-size: .75rem;
		}

		.favorite {
			margin-left: auto;
			transition: opacity $transition, color $transition;
			opacity: 0;
			display: block;

			&:hover,
			&.is-favorite {
				color: var(--warning);
			}
		}

		.favorite.is-favorite,
		&:hover .favorite {
			opacity: 1;
		}

		.title {
			align-self: flex-end;
			font-family: $vikunja-font;
			font-weight: 400;
			font-size: 1.5rem;
			color: var(--text);
			width: 100%;
			margin-bottom: 0;
			max-height: calc(100% - 2rem); // 1rem padding, 1rem height of the "is archived" badge
			overflow: hidden;
			text-overflow: ellipsis;

			display: -webkit-box;
			-webkit-line-clamp: 3;
			-webkit-box-orient: vertical;
		}
	}
}
</style>