<script setup>
import { ref, watch } from 'vue';

import TagSearch from '#/components/tags/search.vue';

import events from '#/src/events.js';

const props = defineProps({
	item: {
		type: Object,
		default: null,
	},
	scene: {
		type: Object,
		default: null,
	},
	edits: {
		type: Object,
		default: () => {},
	},
	editing: {
		type: Set,
		default: null,
	},
});

const emit = defineEmits(['tags']);

const newTags = ref([]);

const tags = [
	{
		tags: props.item.value.filter((tag) => tag.actorId === null),
		actor: null,
		actorId: null,
	},
	...props.scene.actors.map((actor) => ({
		tags: props.item.value.filter((tag) => tag.actorId === actor.id),
		actor,
		actorId: actor?.id || null,
	})),
];

function addTag(newTag, actor) {
	const actorId = actor?.id || null;

	if (props.edits.tags.some((sceneTag) => sceneTag.id === newTag.id && sceneTag.actorId === actorId)) {
		events.emit('feedback', {
			type: 'error',
			message: 'Tag already added',
		});

		return;
	}

	const newTagWithActorId = {
		...newTag,
		actorId,
	};

	newTags.value = newTags.value.concat(newTagWithActorId);
	emit('tags', props.edits.tags.concat(newTagWithActorId));
}

watch(() => props.scene, () => {
	newTags.value = [];
});
</script>

<template>
	<div class="tags-sections">
		<div
			v-for="actorTags in tags"
			:key="`tags-${actorTags.actor?.slug || 'scene'}`"
			class="tags-section"
		>
			<ul
				class="tags nolist"
				:class="{ disabled: !editing.has(item.key) }"
			>
				<li
					v-if="actorTags.actor"
					class="tags-actor"
				>{{ actorTags.actor.name }}:</li>

				<li
					v-for="tag in [...actorTags.tags, ...newTags.filter((newTag) => newTag.actorId === actorTags.actorId)]"
					:key="`tag-${tag.id}`"
					class="tag"
					:class="{ deleted: edits.tags && !edits.tags.some((sceneTag) => sceneTag.id === tag.id && sceneTag.actorId === actorTags.actorId) }"
				>
					<span class="tag-name">{{ tag.name }}</span>

					<Icon
						v-if="edits.tags && !edits.tags.some((sceneTag) => sceneTag.id === tag.id && sceneTag.actorId === actorTags.actorId)"
						icon="checkmark"
						class="add"
						@click="emit('tags', edits.tags.concat(tag))"
					/>

					<Icon
						v-else
						icon="cross2"
						class="remove"
						@click="emit('tags', edits.tags.filter((sceneTag) => !(sceneTag.id === tag.id && sceneTag.actorId === actorTags.actorId)))"
					/>
				</li>

				<li class="new">
					<TagSearch
						:disabled="!editing.has(item.key)"
						@tag="(tag) => addTag(tag, actorTags.actor)"
					>
						<Icon
							icon="plus3"
							class="add"
						/>
					</TagSearch>
				</li>
			</ul>
		</div>
	</div>
</template>

<style scoped>
.tags {
	display: flex;
	flex-wrap: wrap;
	gap: .35rem .25rem;

	&.disabled {
		.tag {
			background: var(--glass-weak-50);
			color: var(--glass-strong-10);

			.remove,
			.add {
				fill: var(--shadow-weak-30);
				background: var(--shadow-weak-50);
			}
		}

		.new .icon {
			background: var(--shadow-weak-40);
		}
	}

	.new {
		display: flex;
		align-items: center;
		margin-left: .25rem;

		&:hover .icon {
			box-shadow: 0 0 3px var(--shadow-weak-20);
		}

		.icon {
			height: 100%;
			padding: 0 .5rem;
			background: var(--success);
			fill: var(--text-light);
		}
	}
}

.tags-sections {
	display: flex;
	flex-direction: column;
	gap: .75rem;
	margin: .5rem 0;
}

.tags-actor {
	margin-right: .5rem;
	font-weight: bold;
}

.tag {
	display: flex;
	align-items: stretch;
	border-radius: .25rem;
	background: var(--background);
	box-shadow: 0 0 3px var(--shadow-weak-30);

	&.deleted  {
		color: var(--glass);
		text-decoration: line-through;
	}
}

.tag,
.new {
	.remove,
	.add,
	.actor {
		height: auto;
		padding: .25rem .3rem;
		margin-left: .25rem;
		border-radius: .25rem;
		fill: var(--highlight-strong-10);

		&:hover {
			fill: var(--text-light);
			cursor: pointer;
		}
	}

	.remove {
		fill: var(--error);

		&:hover {
			background: var(--error);
		}
	}

	.add {
		fill: var(--success);

		&:hover {
			background: var(--success);
		}
	}
}

.tag-name {
	padding: .25rem .5rem;
}
</style>
