<template>
	<!-- 结果图片 -->
	<div class="result-image">
		<div class="header" v-show="showHeader" @mousedown.stop>
			<span class="icon">
				<svg-icon name="chat-compose" size="20" size-unit="px" />
			</span>
			<span class="icon" @click="onPreview">
				<svg-icon name="expand-lg" size="20" size-unit="px" />
			</span>
			<span class="icon" @click="onDownload">
				<svg-icon name="download" size="20" size-unit="px" />
			</span>
			<button class="edit">
				<span class="icon"><svg-icon name="edit" size="13" /></span>
				<span class="text">Edit</span>
			</button>
		</div>
		<img
			class="image"
			:src="data.url"
			:style="{ transform: `scale(${data?.scale?.x || 1}, ${data?.scale?.y || 1})` }"
		/>
		<div class="more" @click="showMenu = !showMenu" @mousedown.stop>
			<svg-icon name="more" size="24" size-unit="px" color="#C9C9C9" />
		</div>
		<div class="menu" v-show="showMenu" @mousedown.stop>
			<div
				v-for="(v, i) in menus"
				:key="i"
				:class="[v.isDivide ? 'divide' : 'item', { disabled: v.disabled }]"
				@click="onMenuItem(v)"
			>
				<template v-if="!v.isDivide">
					<span class="label">{{ v.label }}</span>
					<span class="tip">{{ v.tip }}</span>
				</template>
			</div>
		</div>
	</div>
</template>

<script setup lang="ts">
	import { downloadImage } from '../../../tools/tools'
	import { reactive, ref, onBeforeUnmount, useAttrs, inject, watch } from 'vue'
	const openImagePreview = inject('openImagePreview') as (url: string) => void
	const props = defineProps({
		config: {
			type: Object,
			default: () => ({})
		},
		data: {
			type: Object,
			default: () => ({})
		}
	})
	const emit = defineEmits([
		'delete-node',
		'copy-node',
		'bring-to-font',
		'send-to-back',
		'update-data'
	])
	const attrs = useAttrs()
	const showHeader = ref(!!attrs.node?.data?.isHeader)
	const showMenu = ref(false)
	const data = reactive({
		url: props.data?.url || '',
		scale: props.data?.scale || { x: 1, y: 1 }
	})
	watch(
		() => props.data.url,
		(newVal) => {
			data.url = newVal
		}
	)
	const menus = ref([
		{ label: 'Copy', tip: 'Ctrl+C', on: () => emit('copy-node') },
		{
			label: 'Delete',
			tip: 'Del',
			on: () => emit('delete-node'),
			disabled: !!props.config?.disableDelete
		},
		{ isDivide: true },
		{
			label: 'Bring to font',
			tip: '',
			on: () => {
				emit('bring-to-font')
			}
		},
		{
			label: 'Send to back',
			tip: '',
			on: () => {
				emit('send-to-back')
			}
		},
		{ isDivide: true },
		{
			label: 'Flip horizontal',
			tip: '',
			on: () => {
				data.scale.x = -data.scale.x
				emit('update-data', data)
			}
		},
		{
			label: 'Flip vertical',
			tip: '',
			on: () => {
				data.scale.y = -data.scale.y
				emit('update-data', data)
			}
		}
	])
	const onPreview = () => {
		openImagePreview(data.url)
	}
	const onDownload = () => {
		downloadImage(data.url, 'image.png')
	}
	const onMenuItem = (v) => {
		if (v.disabled) return
		v.on && v.on()
		hideMenu()
	}
	const hideMenu = () => {
		showMenu.value = false
	}
	document.addEventListener('mousedown', hideMenu)
	onBeforeUnmount(() => {
		document.removeEventListener('mousedown', hideMenu)
	})
	defineExpose({ data })
</script>

<style lang="less" scoped>
	.result-image {
		width: 244px;
		border-radius: 16px;
		border: 1px solid #d9d9d9;
		box-shadow: 0 15px 21px 0 rgba(0, 0, 0, 0.05);
		padding: 25px 6px;
		user-select: none;
		background-color: #fff;
		&.active {
			box-shadow: 0 15px 21px 0 rgba(0, 0, 0, 0.05), 0 0 0 2px #d9d9d9;
		}
		> .header {
			position: absolute;
			top: -20px;
			left: 50%;
			transform: translate(-50%, -100%);
			width: auto;
			height: 50px;
			border-radius: 10px;
			border: 2px solid #ebebeb;
			box-shadow: 0px 15px 21px 0px #0000000d;
			display: flex;
			align-items: center;
			justify-content: center;
			user-select: none;
			padding: 0 19px;
			gap: 12px;
			background-color: #fff;
			> .icon {
				cursor: pointer;
				display: flex;
				align-items: center;
				justify-content: center;
				width: 32px;
				height: 32px;
				--svg-icon-color: #000;
				border-radius: 3px;
				&:hover {
					background-color: #ebebeb;
				}
			}
			> .edit {
				width: 80px;
				height: 30px;
				border-radius: 4px;
				border: none;
				background-color: #ED8936;
				color: #fff;
				font-size: 12px;
				display: flex;
				align-items: center;
				justify-content: center;
				gap: 8px;
				&:active {
					opacity: 0.8;
				}
			}
		}

		> .image {
			width: 100%;
			height: auto;
		}
		position: relative;

		> .more {
			position: absolute;
			top: 5px;
			right: 9px;
			width: 24px;
			height: 24px;
			cursor: pointer;
		}
		> .menu {
			position: absolute;
			width: 244px;
			height: auto;
			top: 0;
			right: -10px;
			transform: translate(100%, 0);
			border-radius: 16px;
			padding: 16px 14px;
			box-shadow: 0px 15px 21px 0px rgba(0, 0, 0, 0.05);
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			gap: 12px;
			background-color: #fff;
			z-index: 50;
			> .item {
				width: 100%;
				height: 27px;
				display: flex;
				align-items: center;
				justify-content: space-between;
				padding: 0 8px;
				border-radius: 8px;
				cursor: pointer;
				font-size: 14px;
				&.disabled {
					cursor: not-allowed;
					> .tip,
					> .label {
						color: rgba(0, 0, 0, 0.2);
					}
				}
				&:not(.disabled):hover {
					background: #f3f3f3;
				}
				> .label {
					color: #000;
				}
				> .tip {
					color: rgba(0, 0, 0, 0.3);
				}
			}
			> .divide {
				width: 100%;
				height: 0;
				border-bottom: 1px solid #e5e5e5;
			}
		}
	}
</style>
