<script lang="ts">
	import Selector, { type SELECTOR_TYPE, type SelectorValue } from './Selector.svelte';
	import { createEventDispatcher } from 'svelte';
	import type { IValue } from '@upnd/upend/types';
	import IconButton from './IconButton.svelte';

	const dispatch = createEventDispatcher<{ edit: SelectorValue }>();

	export let editable = true;
	export let value: IValue | undefined = undefined;
	export let types: SELECTOR_TYPE[] | undefined = undefined;
	let newValue: SelectorValue | undefined = value;

	let editing = false;

	let selector: Selector;
	let hover = false;
	let focus = false;

	$: if (editing && selector) selector.focus();
	$: if (!focus && !hover) editing = false;

	function onInput(ev: CustomEvent<SelectorValue>) {
		newValue = ev.detail;
		selector.focus();
	}
</script>

<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
	class="editable"
	class:editing
	on:mouseenter={() => (hover = true)}
	on:mouseleave={() => (hover = false)}
>
	<div class="inner">
		{#if editing}
			<div
				class="selector"
				on:keydown={(ev) => {
					if (ev.key === 'Escape') {
						editing = false;
					}
				}}
			>
				<Selector
					{types}
					initial={value}
					bind:this={selector}
					on:focus={(ev) => (focus = ev.detail)}
					on:input={onInput}
				/>
			</div>
			<IconButton
				name="save"
				on:click={() => {
					if (newValue) dispatch('edit', newValue);
					editing = false;
				}}
			/>
		{:else}
			<div class="content">
				<slot />
			</div>
			{#if editable}
				<div class="edit-icon">
					<IconButton name="edit" on:click={() => (editing = true)} plain />
				</div>
			{/if}
		{/if}
	</div>
</div>

<style lang="scss">
	.editable {
		max-width: 100%;
	}

	.edit-icon {
		opacity: 0;
		transition: opacity 0.2s ease-in-out;
	}

	.editable:hover .edit-icon {
		opacity: 0.8;
	}

	.inner {
		display: flex;
		gap: 0.25em;
		align-items: center;
	}

	.content {
		min-width: 0;
	}

	.selector {
		flex-grow: 1;
		min-width: 0;
	}

	.editing {
		width: 100%;
	}
</style>
