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

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: 200, height: 80 }
): 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.8)',
    strokeWidth = 2,
    dashArray = '5,5'
  } = style;

  // 计算路径
  const path = useMemo(() => 
    calculateCurvePath({
      start: startPoint,
      end: endPoint,
      containerSize,
      curvature
    }), [startPoint, endPoint, containerSize, curvature]);

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

  return (
    <svg
      className="absolute inset-0 pointer-events-none"
      width={containerSize.width}
      height={containerSize.height}
      style={{ zIndex: 10 }}
    >
      {/* 连接线路径 */}
      <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(0 2px 4px rgba(0, 0, 0, 0.2))'
        }}
      />
      
      {/* 连接线末端的小圆点 */}
      <motion.circle
        cx={endPoint.x}
        cy={endPoint.y}
        r={3}
        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(0 2px 4px rgba(0, 0, 0, 0.3))'
        }}
      />

      {/* 动画流动效果（可选） */}
      {animated && (
        <motion.circle
          r={2}
          fill="rgba(255, 255, 255, 0.9)"
          initial={{ opacity: 0 }}
          animate={{
            opacity: [0, 1, 0],
            offsetDistance: ["0%", "100%"]
          }}
          transition={{
            duration: 2,
            repeat: Infinity,
            ease: "linear",
            delay: 0.6
          }}
          style={{
            offsetPath: `path('${path}')`,
            offsetRotate: "0deg"
          }}
        />
      )}
    </svg>
  );
};
