<script setup>
import { computed, onMounted, ref, useId } from 'vue';

import Dialog from '#/components/dialog/dialog.vue';
import Ellipsis from '#/components/loading/ellipsis.vue';

import { get, post } from '#/src/api.js';

const props = defineProps({
	actors: {
		type: Array,
		default: () => [],
	},
});

const emit = defineEmits(['close', 'merged']);

const targetActor = ref(null);
const actorInput = ref(null);
const comment = ref(null);
const actorQuery = ref('');
const actorResults = ref([]);
const submitted = ref(false);
const merged = ref(false);
const searchDropdownId = useId();
const conflictTooltipId = useId();

const sourceTargetConflict = computed(() => props.actors.some((actor) => actor.id === targetActor.value?.id));

async function searchActors() {
	const res = await get('/actors', {
		q: actorQuery.value, // return partial matches
		limit: 10,
		global: true,
	});

	actorResults.value = res.actors;
}

function getActorNames() {
	if (props.actors.length > 1) {
		return `${props.actors.length} actors`;
	}

	if (props.actors[0].entity) {
		return `${props.actors[0].name} (${props.actors[0].entity.name})`;
	}

	return props.actors[0].name;
}

async function merge() {
	submitted.value = true;

	await post(`/actors/${targetActor.value.id}/merge`, {
		actorIds: props.actors.map((actor) => actor.id),
		comment: comment.value || null,
	}, {
		successFeedback: `Merged ${getActorNames()} into ${targetActor.value.name}`,
		errorFeedback: `Failed to merge ${getActorNames()} into ${targetActor.value.name}`,
		appendErrorMessage: true,
	});

	submitted.value = false;
	merged.value = true;

	emit('merged');

	// emit('close');
}

function selectActor(actor) {
	targetActor.value = actor;
	actorQuery.value = '';
	actorResults.value = [];
}

onMounted(() => {
	actorInput.value.focus();
});
</script>

<template>
	<Dialog
		:title="`Merge ${actors.length === 1 ? `'${actors[0].name}'` : `${actors.length} actors`}`"
		@close="emit('close')"
	>
		<div
			v-if="merged"
			class="dialog-body"
		>
			Merge successful

			<ul class="options">
				<li class="option">
					<a
						href=""
						class="link"
					>Reload page</a>
				</li>

				<li class="option">
					<a
						:href="`/actor/${targetActor?.id}/${targetActor?.slug}`"
						class="link"
					>Go to #{{ targetActor?.id }} {{ targetActor?.name }}</a>
				</li>
			</ul>
		</div>

		<div
			v-else
			class="dialog-body"
		>
			<ul class="actors nolist">
				<li
					v-for="actor in actors"
					:key="`actor-${actor.id}`"
					class="actor"
				>
					<span class="source">
						<strong class="source-name">{{ actor.name }}<template v-if="actor.entity"> ({{ actor.entity.name }})</template></strong>
						<span class="source-id">#{{ actor.id }}</span>
					</span>
				</li>
			</ul>

			<span class="path">merging into</span>

			<div
				v-if="targetActor"
				class="target"
			>
				<strong class="target-name">
					<span class="target-id">#{{ targetActor.id }}</span>
					{{ targetActor.name }}
				</strong>

				<Icon
					icon="cross2"
					@click="targetActor = null"
				/>
			</div>

			<template v-else>
				<VDropdown
					:aria-id="searchDropdownId"
					:triggers="[]"
					:shown="actorResults.length > 0"
					:auto-hide="false"
					placement="auto"
				>
					<input
						ref="actorInput"
						v-model="actorQuery"
						class="input"
						placeholder="Search target actor"
						@input="searchActors"
					>

					<template #popper>
						<ul
							class="results nolist"
						>
							<li
								v-for="actorResult in actorResults"
								:key="`actor-result-${actorResult.id}`"
								v-close-popper
								class="result-item"
								@click="selectActor(actorResult)"
							>
								<div class="result-label">
									<span class="result-id">#{{ actorResult.id }}</span> {{ actorResult.name }}
								</div>
							</li>
						</ul>
					</template>
				</VDropdown>
			</template>

			<textarea
				v-model="comment"
				placeholder="Optional comment"
				rows="2"
				class="input comment"
			/>

			<div class="dialog-actions">
				<Ellipsis v-if="submitted" />

				<button
					v-else
					v-tooltip="sourceTargetConflict && { content: 'Cannot merge actor profile into itself', ariaId: conflictTooltipId }"
					type="submit"
					class="button button-primary"
					:disabled="!targetActor || sourceTargetConflict"
					@click="merge"
				>Merge</button>
			</div>
		</div>
	</Dialog>
</template>

<style scoped>
.dialog-body {
	width: 20rem;
	max-width: 100%;
	box-sizing: border-box;
	padding: 1rem;
	gap: 1rem;
	overflow: hidden;
}

.dialog-actions {
	.button {
		width: 100%;
	}
}

.actors {
	max-height: 15rem;
	overflow-y: auto;
}

.actor {
	display: block;
}

.input {
	width: 100%;

	&.comment {
		flex-basis: auto;
	}
}

.path {
	color: var(--glass-strong-20);
}

.target {
	display: flex;
	justify-content: space-between;
	align-items: center;

	.icon {
		padding: .25rem .75rem;
		fill: var(--glass);

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

.source-id,
.target-id {
	font-family: monospace;
	font-size: 1rem;
}

.source {
	display: flex;
}

.source-name {
	flex-grow: 1;
}

.results {
	padding: .25rem 0;
}

.result-item {
	display: flex;
	padding: .25rem .5rem;

	&:hover {
		cursor: pointer;
		color: var(--primary);
	}
}

.result-id {
	font-family: monospace;
	font-size: 1rem;
}

.load-container {
	height: 2rem;
	display: flex;
	justify-content: center;
	align-items: center;
	box-sizing: border-box;
	padding: 0 1rem;
}

.options {
	padding: 0 1.5rem;
	margin: 0;
	line-height: 1.75;
}
</style>
