<script setup lang="ts">
import { computed, ref } from 'vue'
import { useVueFlowContext } from '../../../hooks/useVueFlowContext'

const props = defineProps<{
	id: string
	nodeId?: string
	position: string
	type: 'source' | 'target'
	label?: string
	labelStyle?: Record<string, any>
	showAddAction?: boolean
}>()

const emit = defineEmits<{
	add: [event: MouseEvent]
}>()

const vueFlowContext = useVueFlowContext()
const shouldShowAddAction = computed(() => props.type === 'source' && props.showAddAction !== false)
const isConnecting = computed(
	() =>
		vueFlowContext.connectingHandle.value &&
		vueFlowContext.connectingHandle.value?.handleId === props.id
)
const isHovered = ref(false)

const isHandlePlusVisible = computed(() => !isConnecting.value || isHovered.value)

function onMouseEnter() {
	isHovered.value = true
}

function onMouseLeave() {
	isHovered.value = false
}

const onAdd = (event: MouseEvent) => {
	emit('add', event)
}
</script>

<template>
	<div :class="[position, type]" class="renderType flex items-center">
		<div :class="type" class="handlePort transition-transform duration-150 relative"></div>
		<Transition name="canvas-node-handle-main-output">
			<svg
				v-if="shouldShowAddAction"
				v-show="isHandlePlusVisible"
				data-test-id="canvas-handle-plus-wrapper"
				class="handleAddAction"
				viewBox="0 0 44 24"
				aria-hidden="true"
				@mouseenter="onMouseEnter"
				@mouseleave="onMouseLeave"
			>
				<line x1="0" y1="12" x2="21" y2="12" class="handleAddAction__line" stroke-width="2" />
				<g
					data-test-id="canvas-handle-plus"
					class="handleAddAction__plus clickable"
					transform="translate(20, 0)"
					@click.stop="onAdd"
				>
					<rect x="2" y="2" width="20" height="20" rx="4" class="handleAddAction__rect clickable" />
					<path
						d="M8 12h8m-4-4v8"
						class="handleAddAction__icon clickable"
						stroke-width="1.5"
						stroke-linecap="round"
						stroke-linejoin="round"
					/>
				</g>
			</svg>
		</Transition>

		<div v-if="label" class="w-max ml-8px text-12px text-#666 bg-#f5f5f5" :style="labelStyle">
			{{ label }}
		</div>
	</div>
</template>

<style lang="less" scoped>
.handlePort {
	width: 12px;
	height: 12px;
	background-color: #fff;
	border: 1px solid #989898;
	border-radius: 50%;
	cursor: default;
	flex-shrink: 0;
}

.handleAddAction {
	width: 44px;
	height: 24px;
	flex-shrink: 0;
	overflow: visible;
	pointer-events: none;
}

.handleAddAction__line {
	stroke: #d1d5db;
	pointer-events: none;
}

.handleAddAction__plus {
	color: #4b5563;
	transform-origin: center;
	transition:
		transform 0.15s ease,
		color 0.15s ease;
	pointer-events: auto;
}

.handleAddAction__rect {
	fill: #ececec;
	stroke: #d6d6d6;
	transition:
		fill 0.15s ease,
		stroke 0.15s ease;
}

.handleAddAction__icon {
	stroke: currentColor;
}

.handleAddAction__plus:hover {
	color: #111827;
	transform: translate(20px, 0) scale(1.04);
}

.handleAddAction__plus:hover .handleAddAction__rect {
	fill: #e5e7eb;
	stroke: #cfd4dc;
}

.source:hover {
	transform: scale(1.2);
	border-width: 1.2px;
	cursor: crosshair;
}

.renderType {
	overflow: visible;

	&.top {
		margin-bottom: -16px;
		transform: translate(0%, -50%);
	}

	&.right {
		margin-left: -16px;
		transform: translate(50%, 0%);
	}

	&.left {
		margin-right: -16px;
		transform: translate(-50%, 0%);
	}

	&.bottom {
		margin-top: -16px;
		transform: translate(0%, 50%);
	}
}

.canvas-node-handle-main-output-enter-active,
.canvas-node-handle-main-output-leave-active {
	transform-origin: 0 center;
	transition-property: transform, opacity;
	transition-duration: 0.2s;
	transition-timing-function: ease;
}

.canvas-node-handle-main-output-enter-from,
.canvas-node-handle-main-output-leave-to {
	transform: scale(0);
	opacity: 0;
}
</style>
