<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import { BaseEdge, EdgeLabelRenderer, type EdgeProps, type Connection } from '@vue-flow/core'
import { IconButton } from '@repo/ui'
import type { CanvasExecutionStatus } from '../../../Interface'
import { getExecutionStatusColor } from '../../../utils/execution-status'
import { getEdgeRenderData } from './utils/getEdgeRenderData'
import { useVueFlowContext } from '../../../hooks/useVueFlowContext'

defineOptions({
	inheritAttrs: false
})

const emit = defineEmits<{
	delete: [connection: Connection]
	add: [connection: Connection]
}>()

type CanvasEdgeProps = EdgeProps & {
	readOnly?: boolean
	hovered?: boolean
	bringToFront?: boolean
}

const props = defineProps<CanvasEdgeProps>()
const { vueFlow } = useVueFlowContext()

// 缩放补偿：工具栏大小随缩放调整，保持视觉一致
const zoom = computed(() => vueFlow.viewport.value.zoom)
const zoomCompensationFactor = computed(() => 1 / zoom.value)
const EDGE_STROKE_WIDTH = '1.5px'

// 执行状态
const executionStatus = computed<CanvasExecutionStatus>(
	() => (props.data?.executionStatus as CanvasExecutionStatus) || 'idle'
)
const isPendingEdge = computed(() => !!props.data?.pending)
const isRunningEdge = computed(() => executionStatus.value === 'running')

// 边线路径数据（含反向连接绕行处理）
const renderData = computed(() =>
	getEdgeRenderData({
		sourceX: props.sourceX,
		sourceY: props.sourceY,
		sourcePosition: props.sourcePosition,
		targetX: props.targetX,
		targetY: props.targetY,
		targetPosition: props.targetPosition
	})
)

const segments = computed(() => renderData.value.segments)
const labelPosition = computed(() => renderData.value.labelPosition)

// CSS 变量驱动的颜色，便于暗黑模式适配
const edgeColor = computed(() => {
	if (isPendingEdge.value) return '#409EFF'
	return getExecutionStatusColor(executionStatus.value)
})

const edgeStyles = computed(() => {
	const status = executionStatus.value
	const styles: Record<string, string> = {
		'--canvas-edge-color': edgeColor.value,
		'--canvas-edge-stroke-width': EDGE_STROKE_WIDTH
	}
	if (status !== 'idle' && !isPendingEdge.value) {
		styles['--canvas-edge-filter'] = `drop-shadow(0 0 6px ${edgeColor.value}55)`
	}
	return styles
})

const edgeClasses = computed(() => ({
	'canvas-edge-path': true,
	'is-pending': isPendingEdge.value,
	'is-running': isRunningEdge.value
}))

// 延迟 hover（避免鼠标快速划过时闪烁）
const delayedHovered = ref(props.hovered)
const delayedHoveredSetTimeoutRef = ref<ReturnType<typeof setTimeout> | null>(null)
const delayedHoveredTimeout = 600

const connection = computed<Connection>(() => ({
	source: props.source,
	target: props.target,
	sourceHandle: props.sourceHandleId,
	targetHandle: props.targetHandleId,
	id: props.id
}))

watch(
	() => props.hovered,
	(isHovered) => {
		if (isHovered) {
			if (delayedHoveredSetTimeoutRef.value) clearTimeout(delayedHoveredSetTimeoutRef.value)
			delayedHovered.value = true
		} else {
			delayedHoveredSetTimeoutRef.value = setTimeout(() => {
				delayedHovered.value = false
			}, delayedHoveredTimeout)
		}
	},
	{ immediate: true }
)

const renderToolbar = computed(() => delayedHovered.value && !props.readOnly)

const toolbarStyle = computed(() => ({
	pointerEvents: 'all' as const,
	position: 'absolute' as const,
	transform: `translate(-50%, -50%) translate(${labelPosition.value[0]}px, ${labelPosition.value[1]}px) scale(${zoomCompensationFactor.value})`
}))

const onAdd = () => emit('add', connection.value)
const onDelete = () => emit('delete', connection.value)
</script>

<template>
	<!-- 多段路径（反向连接时会有两段） -->
	<BaseEdge
		v-for="(segment, index) in segments"
		:key="`${id}-${index}`"
		:path="segment[0]"
		:marker-end="markerEnd"
		:interaction-width="40"
		:style="edgeStyles"
		:class="edgeClasses"
	/>

	<EdgeLabelRenderer>
		<div :style="toolbarStyle" class="nodrag nopan">
			<div v-if="isPendingEdge" class="text-sm text-gray-500">pendding...</div>
			<div v-if="renderToolbar && !isPendingEdge" class="flex">
				<IconButton :edge-add-btn="id" icon="lucide:plus" size="small" square @click="onAdd" />
				<IconButton icon="lucide:brush-cleaning" size="small" square @click="onDelete" />
			</div>
		</div>
	</EdgeLabelRenderer>
</template>

<style>
/* ── 基础边线样式 ── */
.canvas-edge-path {
	stroke: var(--canvas-edge-color, #b1b1b7);
	stroke-width: var(--canvas-edge-stroke-width, 2px);
	stroke-linecap: round;
	filter: var(--canvas-edge-filter, none);
	transition:
		stroke 180ms ease,
		stroke-width 180ms ease,
		filter 180ms ease,
		opacity 180ms ease;
}

/* ── Pending: 虚线流动 ── */
.canvas-edge-path.is-pending {
	opacity: 0.7;
	stroke-dasharray: 8 6;
	animation: edge-loading-dash 3.6s linear infinite;
}

/* ── Running: 快速流动虚线 ── */
.canvas-edge-path.is-running {
	stroke-dasharray: 6 4;
	animation: edge-running-dash 1s linear infinite;
}

@keyframes edge-loading-dash {
	from {
		stroke-dashoffset: 0;
	}
	to {
		stroke-dashoffset: -28;
	}
}

@keyframes edge-running-dash {
	from {
		stroke-dashoffset: 0;
	}
	to {
		stroke-dashoffset: -20;
	}
}
</style>
