<template>
	<Dialog
		:title="`Merge '${actor.name}'`"
		@close="emit('close')"
	>
		<div class="dialog-body">
			<strong class="source">#{{ actor.id }} {{ actor.name }}<span v-if="actor.entity"> ({{ actor.entity.name }})</span></strong>

			<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
					:triggers="[]"
					:shown="actorResults.length > 0"
					:auto-hide="false"
				>
					<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>

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

				<button
					v-else
					type="submit"
					class="button button-primary"
					:disabled="!targetActor"
					@click="merge"
				>Merge</button>
			</div>
		</div>
	</Dialog>
</template>

<script setup>
import { ref, onMounted } 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({
	actor: {
		type: Object,
		default: null,
	},
});

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

const targetActor = ref(null);
const actorInput = ref(null);
const actorQuery = ref('');
const actorResults = ref([]);
const submitted = ref(false);

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

	actorResults.value = res.actors;
}

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

	await post(`/actors/${targetActor.value.id}/merge/${props.actor.id}`, null, {
		successFeedback: `Merged ${props.actor.entity ? `${props.actor.name} (${props.actor.entity.name})` : props.actor.name} into ${targetActor.value.name}`,
		errorFeedback: `Failed to merge ${props.actor.entity ? `${props.actor.name} (${props.actor.entity.name})` : props.actor.name} into ${targetActor.value.name}`,
		appendErrorMessage: true,
	});

	submitted.value = false;

	emit('close');
}

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

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

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

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

.input {
	width: 100%;
}

.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;
		}
	}
}

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

.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;
}
</style>
