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

import React, { useMemo } from 'react';
import { motion } from 'framer-motion';
import { ConnectionPathParams, InputBoxPosition } from './types';
import {
  CONNECTION_STYLE,
  ARROW_GEOMETRY,
  calculateArrowGeometry,
  calculateCurvePath as calculateUnifiedCurvePath,
  getConnectionAnimationConfig
} from './connection-config';

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 - 8; // 向内偏移8px，指向输入框内部
    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 + 8; // 向内偏移8px，指向输入框内部
    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 - 8; // 向内偏移8px，指向输入框内部
  }
  // 最后选择上方
  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 + 8; // 向内偏移8px，指向输入框内部
  }
  // 如果空间不足，强制放在右侧并调整位置
  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 - 8; // 向内偏移8px，指向输入框内部
    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 = CONNECTION_STYLE.color,
    strokeWidth = CONNECTION_STYLE.strokeWidth,
    dashArray = CONNECTION_STYLE.dashArray
  } = style;

  // 使用统一的箭头几何计算
  const arrowGeometry = useMemo(() =>
    calculateArrowGeometry(startPoint, endPoint),
    [startPoint, endPoint]
  );

  // 使用统一的路径计算
  const path = useMemo(() =>
    calculateUnifiedCurvePath(startPoint, arrowGeometry.center, containerSize),
    [startPoint, arrowGeometry.center, containerSize]
  );

  // 获取统一的动画配置
  const animationConfig = useMemo(() =>
    getConnectionAnimationConfig(animated),
    [animated]
  );

  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={animationConfig.line.initial}
        animate={animationConfig.line.animate}
        transition={animationConfig.line.transition}
        style={{
          filter: CONNECTION_STYLE.dropShadow
        }}
      />

      {/* 几何精确的箭头 - 与连接线完美对齐 */}
      <motion.polygon
        points={arrowGeometry.points.map(p => `${p.x},${p.y}`).join(' ')}
        fill={color}
        initial={animationConfig.arrow.initial}
        animate={animationConfig.arrow.animate}
        transition={animationConfig.arrow.transition}
        style={{
          filter: CONNECTION_STYLE.dropShadow
        }}
      />

      {/* 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>
  );
};
