/**
 * 编辑连接线组件
 * 实现从编辑点到输入框的弧线连接
 */

import React, { useMemo } from 'react';
import { motion } from 'framer-motion';
import { ConnectionPathParams, InputBoxPosition } from './types';

interface EditConnectionProps {
  /** 起始点坐标（编辑点位置） */
  startPoint: { x: number; y: number };
  /** 结束点坐标（输入框位置） */
  endPoint: { x: number; y: number };
  /** 容器尺寸 */
  containerSize: { width: number; height: number };
  /** 连接线样式 */
  style?: {
    color?: string;
    strokeWidth?: number;
    dashArray?: string;
  };
  /** 弧线弯曲程度 */
  curvature?: number;
  /** 是否显示动画 */
  animated?: boolean;
}

/**
 * 计算弧线路径
 */
function calculateCurvePath({
  start,
  end,
  containerSize,
  curvature = 0.3
}: ConnectionPathParams): string {
  const dx = end.x - start.x;
  const dy = end.y - start.y;
  const distance = Math.sqrt(dx * dx + dy * dy);
  
  // 计算控制点，创建优雅的弧线
  const midX = (start.x + end.x) / 2;
  const midY = (start.y + end.y) / 2;
  
  // 根据方向调整控制点
  let controlX = midX;
  let controlY = midY;
  
  // 如果是水平方向较长，控制点偏向垂直方向
  if (Math.abs(dx) > Math.abs(dy)) {
    controlY = midY + (dy > 0 ? -1 : 1) * distance * curvature;
  } else {
    // 如果是垂直方向较长，控制点偏向水平方向
    controlX = midX + (dx > 0 ? -1 : 1) * distance * curvature;
  }
  
  // 确保控制点在容器范围内
  controlX = Math.max(10, Math.min(containerSize.width - 10, controlX));
  controlY = Math.max(10, Math.min(containerSize.height - 10, controlY));
  
  // 创建二次贝塞尔曲线路径
  return `M ${start.x} ${start.y} Q ${controlX} ${controlY} ${end.x} ${end.y}`;
}

/**
 * 计算最佳输入框位置
 */
export function calculateInputPosition(
  editPointPosition: { x: number; y: number },
  containerSize: { width: number; height: number },
  inputBoxSize: { width: number; height: number } = { width: 300, height: 50 }
): InputBoxPosition {
  const { x: pointX, y: pointY } = editPointPosition;
  const { width: containerWidth, height: containerHeight } = containerSize;
  const { width: inputWidth, height: inputHeight } = inputBoxSize;
  
  const margin = 20; // 与边界的最小距离
  const connectionLength = 80; // 连接线长度
  
  // 计算各个方向的可用空间
  const spaceTop = pointY;
  const spaceBottom = containerHeight - pointY;
  const spaceLeft = pointX;
  const spaceRight = containerWidth - pointX;
  
  let direction: 'top' | 'bottom' | 'left' | 'right' = 'right';
  let inputX = pointX + connectionLength;
  let inputY = pointY - inputHeight / 2;
  let connectionEndX = pointX + connectionLength;
  let connectionEndY = pointY;
  
  // 优先选择右侧
  if (spaceRight >= inputWidth + connectionLength + margin) {
    direction = 'right';
    inputX = pointX + connectionLength;
    inputY = Math.max(margin, Math.min(containerHeight - inputHeight - margin, pointY - inputHeight / 2));
    connectionEndX = inputX;
    connectionEndY = inputY + inputHeight / 2;
  }
  // 其次选择左侧
  else if (spaceLeft >= inputWidth + connectionLength + margin) {
    direction = 'left';
    inputX = pointX - connectionLength - inputWidth;
    inputY = Math.max(margin, Math.min(containerHeight - inputHeight - margin, pointY - inputHeight / 2));
    connectionEndX = inputX + inputWidth;
    connectionEndY = inputY + inputHeight / 2;
  }
  // 然后选择下方
  else if (spaceBottom >= inputHeight + connectionLength + margin) {
    direction = 'bottom';
    inputX = Math.max(margin, Math.min(containerWidth - inputWidth - margin, pointX - inputWidth / 2));
    inputY = pointY + connectionLength;
    connectionEndX = inputX + inputWidth / 2;
    connectionEndY = inputY;
  }
  // 最后选择上方
  else if (spaceTop >= inputHeight + connectionLength + margin) {
    direction = 'top';
    inputX = Math.max(margin, Math.min(containerWidth - inputWidth - margin, pointX - inputWidth / 2));
    inputY = pointY - connectionLength - inputHeight;
    connectionEndX = inputX + inputWidth / 2;
    connectionEndY = inputY + inputHeight;
  }
  // 如果空间不足，强制放在右侧并调整位置
  else {
    direction = 'right';
    inputX = Math.min(containerWidth - inputWidth - margin, pointX + 40);
    inputY = Math.max(margin, Math.min(containerHeight - inputHeight - margin, pointY - inputHeight / 2));
    connectionEndX = inputX;
    connectionEndY = inputY + inputHeight / 2;
  }
  
  return {
    x: inputX,
    y: inputY,
    connectionEnd: { x: connectionEndX, y: connectionEndY },
    direction
  };
}

/**
 * 编辑连接线组件
 */
export const EditConnection: React.FC<EditConnectionProps> = ({
  startPoint,
  endPoint,
  containerSize,
  style = {},
  curvature = 0.3,
  animated = true
}) => {
  const {
    color = 'rgba(255, 255, 255, 0.9)', // White color to match the reference image
    strokeWidth = 2,
    dashArray = '8,4' // Dashed line to match the reference image
  } = style;

  // 计算箭头几何参数
  const arrowSize = 8;
  const arrowHalfHeight = 4;

  // 计算连接方向和角度
  const connectionVector = useMemo(() => {
    const dx = endPoint.x - startPoint.x;
    const dy = endPoint.y - startPoint.y;
    const length = Math.sqrt(dx * dx + dy * dy);
    return {
      dx: dx / length,
      dy: dy / length,
      angle: Math.atan2(dy, dx)
    };
  }, [startPoint, endPoint]);

  // 计算箭头的正确位置和线条终点
  const arrowGeometry = useMemo(() => {
    const { dx, dy, angle } = connectionVector;

    // 箭头尖端位置（原endPoint）
    const arrowTip = { x: endPoint.x, y: endPoint.y };

    // 箭头底部中心点（线条应该连接到这里）
    const arrowBase = {
      x: endPoint.x - dx * arrowSize,
      y: endPoint.y - dy * arrowSize
    };

    // 计算箭头三角形的三个顶点
    const perpX = -dy; // 垂直向量X
    const perpY = dx;  // 垂直向量Y

    const arrowPoints = [
      arrowTip, // 尖端
      {
        x: arrowBase.x + perpX * arrowHalfHeight,
        y: arrowBase.y + perpY * arrowHalfHeight
      },
      {
        x: arrowBase.x - perpX * arrowHalfHeight,
        y: arrowBase.y - perpY * arrowHalfHeight
      }
    ];

    return {
      tip: arrowTip,
      base: arrowBase,
      points: arrowPoints,
      angle
    };
  }, [endPoint, connectionVector, arrowSize, arrowHalfHeight]);

  // 计算路径（线条终止于箭头底部中心）
  const path = useMemo(() =>
    calculateCurvePath({
      start: startPoint,
      end: arrowGeometry.base, // 连接到箭头底部中心而不是尖端
      containerSize,
      curvature
    }), [startPoint, arrowGeometry.base, containerSize, curvature]);

  // 计算路径长度用于动画
  const pathLength = useMemo(() => {
    const dx = arrowGeometry.base.x - startPoint.x;
    const dy = arrowGeometry.base.y - startPoint.y;
    return Math.sqrt(dx * dx + dy * dy) * 1.2; // 弧线比直线长约20%
  }, [startPoint, arrowGeometry.base]);

  return (
    <svg
      className="absolute inset-0 pointer-events-none"
      width={containerSize.width}
      height={containerSize.height}
      style={{ zIndex: 10 }}
    >
      {/* Curved dashed line - properly aligned to arrow base center */}
      <motion.path
        d={path}
        fill="none"
        stroke={color}
        strokeWidth={strokeWidth}
        strokeDasharray={dashArray}
        strokeLinecap="round"
        strokeLinejoin="round"
        initial={animated ? {
          pathLength: 0,
          opacity: 0
        } : {}}
        animate={animated ? {
          pathLength: 1,
          opacity: 1
        } : {}}
        transition={animated ? {
          pathLength: { duration: 0.6, ease: "easeInOut" },
          opacity: { duration: 0.3 }
        } : {}}
        style={{
          filter: 'drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.8))'
        }}
      />

      {/* Properly aligned arrow head with geometric precision */}
      <motion.polygon
        points={arrowGeometry.points.map(p => `${p.x},${p.y}`).join(' ')}
        fill={color}
        initial={animated ? {
          scale: 0,
          opacity: 0
        } : {}}
        animate={animated ? {
          scale: 1,
          opacity: 1
        } : {}}
        transition={animated ? {
          delay: 0.4,
          duration: 0.3,
          type: "spring",
          stiffness: 300,
          damping: 25
        } : {}}
        style={{
          filter: 'drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.8))'
        }}
      />

      {/* Debug visualization (remove in production) */}
      {process.env.NODE_ENV === 'development' && (
        <>
          {/* Arrow base center point */}
          <circle
            cx={arrowGeometry.base.x}
            cy={arrowGeometry.base.y}
            r={1}
            fill="red"
            opacity={0.5}
          />
          {/* Arrow tip point */}
          <circle
            cx={arrowGeometry.tip.x}
            cy={arrowGeometry.tip.y}
            r={1}
            fill="blue"
            opacity={0.5}
          />
        </>
      )}

    </svg>
  );
};
