<script setup>
import { BaseEdge, EdgeLabelRenderer, getSmoothStepPath, useVueFlow } from '@vue-flow/core'
import { computed, ref, watch } from 'vue'

const props = defineProps({
  id: String,
  sourceX: Number,
  sourceY: Number,
  targetX: Number,
  targetY: Number,
  sourcePosition: String,
  targetPosition: String,
  selected: Boolean,
  animated: Boolean,
  label: String,
  style: Object,
  markerEnd: String,
  data: Object
})

const { updateEdgeData } = useVueFlow()

// Custom path offset for manual positioning
const pathOffset = ref({ x: 0, y: 0 })

// Initialize from saved data
if (props.data?.pathOffset) {
  pathOffset.value = props.data.pathOffset
}

// Calculate edge path with custom offset
const path = computed(() => {
  try {
    // Apply the offset to create a custom control point
    const centerX = (props.sourceX + props.targetX) / 2 + pathOffset.value.x
    const centerY = (props.sourceY + props.targetY) / 2 + pathOffset.value.y
    
    const [edgePath, labelX, labelY] = getSmoothStepPath({
      sourceX: props.sourceX,
      sourceY: props.sourceY,
      sourcePosition: props.sourcePosition,
      targetX: props.targetX,
      targetY: props.targetY,
      targetPosition: props.targetPosition,
      borderRadius: 8,
      offset: 20,
      // Override center point with our custom position
      centerX,
      centerY
    })
    
    return {
      path: edgePath,
      labelX: labelX || centerX,
      labelY: labelY || centerY,
      controlX: centerX,
      controlY: centerY
    }
  } catch (error) {
    // Fallback to simple calculation
    const centerX = (props.sourceX + props.targetX) / 2 + pathOffset.value.x
    const centerY = (props.sourceY + props.targetY) / 2 + pathOffset.value.y
    return {
      path: `M ${props.sourceX} ${props.sourceY} Q ${centerX} ${centerY} ${props.targetX} ${props.targetY}`,
      labelX: centerX,
      labelY: centerY,
      controlX: centerX,
      controlY: centerY
    }
  }
})

const edgeStyle = computed(() => ({
  stroke: props.selected ? '#ff6b6b' : '#555',
  strokeWidth: props.selected ? 3 : 2,
  strokeDasharray: props.animated ? '5,5' : 'none',
  ...props.style
}))

const markerEndUrl = computed(() => {
  return props.selected ? 'url(#arrow-selected)' : 'url(#arrow)'
})

// Drag handling for control point
const isDragging = ref(false)

const onControlPointMouseDown = (event) => {
  event.preventDefault()
  event.stopPropagation()
  
  isDragging.value = true
  const startX = event.clientX
  const startY = event.clientY
  const startOffsetX = pathOffset.value.x
  const startOffsetY = pathOffset.value.y
  
  const onMouseMove = (moveEvent) => {
    if (!isDragging.value) return
    
    const deltaX = moveEvent.clientX - startX
    const deltaY = moveEvent.clientY - startY
    
    // Apply zoom factor (assuming 1.0 for now, can be enhanced)
    pathOffset.value = {
      x: startOffsetX + deltaX,
      y: startOffsetY + deltaY
    }
  }
  
  const onMouseUp = () => {
    isDragging.value = false
    
    // Save the new path offset to edge data
    if (props.id && updateEdgeData) {
      updateEdgeData(props.id, {
        ...props.data,
        pathOffset: pathOffset.value
      })
    }
    
    document.removeEventListener('mousemove', onMouseMove)
    document.removeEventListener('mouseup', onMouseUp)
  }
  
  document.addEventListener('mousemove', onMouseMove)
  document.addEventListener('mouseup', onMouseUp)
}

// Reset path offset
const resetPath = () => {
  pathOffset.value = { x: 0, y: 0 }
  if (props.id && updateEdgeData) {
    updateEdgeData(props.id, {
      ...props.data,
      pathOffset: undefined
    })
  }
}
</script>

<script>
export default {
  inheritAttrs: false,
}
</script>

<template>
  <!-- Main edge path -->
  <BaseEdge 
    :path="path.path" 
    :style="edgeStyle"
    :marker-end="markerEndUrl"
    :class="{
      'animated': animated,
      'selected': selected
    }"
  />

  <!-- Control point for edge repositioning (only when selected) -->
  <g v-if="selected" class="edge-controls">
    <!-- Control point circle -->
    <circle
      :cx="path.controlX"
      :cy="path.controlY"
      r="4"
      fill="#3b82f6"
      stroke="white"
      stroke-width="2"
      class="edge-control-point"
      style="cursor: move;"
      @mousedown="onControlPointMouseDown"
    />
    
    <!-- Larger invisible area for easier clicking -->
    <circle
      :cx="path.controlX"
      :cy="path.controlY"
      r="12"
      fill="transparent"
      class="edge-control-area"
      style="cursor: move;"
      @mousedown="onControlPointMouseDown"
    />
    
    <!-- Visual indicator for draggable control -->
    <circle
      :cx="path.controlX"
      :cy="path.controlY"
      r="8"
      fill="rgba(59, 130, 246, 0.2)"
      class="edge-control-indicator"
      style="pointer-events: none;"
    />
  </g>

  <!-- Edge label if provided -->
  <EdgeLabelRenderer v-if="label">
    <div
      :style="{
        position: 'absolute',
        transform: `translate(-50%, -50%) translate(${path.labelX}px, ${path.labelY}px)`,
        pointerEvents: 'all',
        fontSize: '11px',
        fontWeight: '600',
        background: 'white',
        padding: '3px 8px',
        borderRadius: '12px',
        border: '1.5px solid #3b82f6',
        boxShadow: '0 2px 8px rgba(59, 130, 246, 0.2)',
        color: '#1e40af',
        whiteSpace: 'nowrap',
        zIndex: 10
      }"
      class="edge-label nodrag nopan"
    >
      {{ label }}
    </div>
  </EdgeLabelRenderer>

  <!-- Reset button for custom positioning -->
  <EdgeLabelRenderer v-if="selected && (pathOffset.x !== 0 || pathOffset.y !== 0)">
    <div
      :style="{
        position: 'absolute',
        transform: `translate(-50%, -50%) translate(${path.controlX + 20}px, ${path.controlY - 20}px)`,
        pointerEvents: 'all'
      }"
      class="edge-reset-button nodrag nopan"
    >
      <button
        @click="resetPath"
        style="
          background: #ef4444;
          color: white;
          border: none;
          border-radius: 3px;
          padding: 2px 6px;
          font-size: 10px;
          cursor: pointer;
          box-shadow: 0 1px 3px rgba(0,0,0,0.2);
        "
        title="Reset edge path"
      >
        Reset
      </button>
    </div>
  </EdgeLabelRenderer>
</template>

<style scoped>
.edge-control-point {
  transition: r 0.2s ease;
}

.edge-control-point:hover {
  r: 5;
}

.animated {
  animation: dash 2s linear infinite;
}

@keyframes dash {
  to {
    stroke-dashoffset: -10;
  }
}
</style> 