<template>
	<span
		class="editable-input"
		:class="{ 'is-editing': isEditing }"
		@dblclick.stop="startEdit"
		@keydown.enter="finishEdit"
		@keydown.escape="cancelEdit"
		tabindex="0"
	>
		<span v-if="!isEditing" class="editable-text">
			{{ displayText }}
		</span>
		<input
			v-else
			ref="inputRef"
			type="text"
			class="form-control"
			v-model="editValue"
			@blur="finishEdit"
			@keydown.enter="finishEdit"
			@keydown.escape="cancelEdit"
		/>
	</span>
</template>

<script setup>
import { ref, computed, nextTick } from "vue";

const props = defineProps({
	text: {
		type: String,
		default: ""
	},
	placeholder: {
		type: String,
		default: ""
	},
	emptyLabel: {
		type: String,
		default: ""
	}
});

const emit = defineEmits(["update:modelValue"]);

const isEditing = ref(false);
const editValue = ref("");
const inputRef = ref(null);

const displayText = computed(() => {
	if (props.text) return props.text;
	if (props.emptyLabel) return props.emptyLabel;
	return props.placeholder || "点击编辑";
});

async function startEdit() {
	isEditing.value = true;
	editValue.value = props.text;
	
	await nextTick();
	inputRef.value?.focus();
	inputRef.value?.select();
}

function finishEdit() {
	if (isEditing.value) {
		emit("update:modelValue", editValue.value);
		isEditing.value = false;
	}
}

function cancelEdit() {
	editValue.value = props.text;
	isEditing.value = false;
}
</script>

<style lang="scss" scoped>
.editable-input {
	display: inline-block;
	cursor: pointer;
	
	&:hover {
		background-color: var(--bg-light-gray);
		border-radius: var(--border-radius-sm);
		padding: 0.2rem 0.4rem;
		margin: -0.2rem -0.4rem;
	}
	
	&.is-editing {
		.form-control {
			border: 1px solid var(--border-primary);
			outline: none;
			background-color: var(--fg-color);
		}
	}
	
	.editable-text {
		display: inline-block;
		min-width: 1rem;
		min-height: 1.2rem;
	}
}
</style>