import { useEffect, useState, useMemo, useCallback } from 'react';
import { useRackStore } from '../../store/useRackStore';

export function ConnectionLayer() {
  const { racks, cablingFromPortId } = useRackStore();
  const [coords, setCoords] = useState<Record<string, { x: number; y: number }>>({});
  const [mousePos, setMousePos] = useState({ x: 0, y: 0 });

  // Update port coordinates
  const updateCoords = useCallback(() => {
    const newCoords: Record<string, { x: number; y: number }> = {};
    const dots = document.querySelectorAll('[data-port-id]');
    
    // Find the closest scrollable parent that defines our coordinate system
    // RackPlanner has overflow-auto on the canvas wrapper
    const canvas = document.querySelector('.rack-planner-canvas');
    if (!canvas) return;
    
    const canvasRect = canvas.getBoundingClientRect();

    dots.forEach((dot) => {
      const portId = (dot as HTMLElement).dataset.portId;
      if (!portId) return;
      const rect = dot.getBoundingClientRect();
      
      // Coordinate is relative to the canvas origin, including its scroll position
      newCoords[portId] = {
        x: rect.left + rect.width / 2 - canvasRect.left + canvas.scrollLeft,
        y: rect.top + rect.height / 2 - canvasRect.top + canvas.scrollTop,
      };
    });
    setCoords(newCoords);
  }, []);

  useEffect(() => {
    updateCoords();
    // Re-calculate on window resize or when racks change (modules move)
    window.addEventListener('resize', updateCoords);
    
    // Also re-calculate if the user scrolls (though ideally lines are pinned to the canvas)
    // Actually, if SVG is INSIDE the scrollable container, we don't need scroll adjustment.
    
    // We'll use a MutationObserver to detect DOM changes (like modules being added/moved)
    const observer = new MutationObserver(updateCoords);
    const canvas = document.querySelector('.rack-planner-canvas');
    if (canvas) {
      observer.observe(canvas, { childList: true, subtree: true, attributes: true });
    }

    return () => {
      window.removeEventListener('resize', updateCoords);
      observer.disconnect();
    };
  }, [racks, updateCoords]);

  // Track mouse for "draft" connection (only while actively cabling)
  useEffect(() => {
    if (!cablingFromPortId) return;
    
    const onMouseMove = (e: MouseEvent) => {
      const canvas = document.querySelector('.rack-planner-canvas');
      if (!canvas) return;
      const rect = canvas.getBoundingClientRect();
      setMousePos({
        x: e.clientX - rect.left + canvas.scrollLeft,
        y: e.clientY - rect.top + canvas.scrollTop,
      });
    };
    
    window.addEventListener('mousemove', onMouseMove);
    return () => window.removeEventListener('mousemove', onMouseMove);
  }, [cablingFromPortId]);

  const connections = useMemo(() => {
    const conns: { id: string; from: string; to: string; color?: string; fromRackId: string; toRackId: string }[] = [];
    racks.forEach((rack) => {
      rack.modules.forEach((mod) => {
        mod.ports.forEach((port) => {
          port.sourceConnections?.forEach((c) => {
            conns.push({ 
              id: c.id, 
              from: c.fromPortId, 
              to: c.toPortId, 
              color: c.color,
              fromRackId: rack.id,
              toRackId: '' // We don't easily know the destination rack without searching
            });
          });
        });
      });
    });
    return conns;
  }, [racks]);

  // Decide if we should show draft line
  const draftStart = cablingFromPortId ? coords[cablingFromPortId] : null;

  return (
    <svg 
      className="absolute top-0 left-0 pointer-events-none z-20 overflow-visible" 
      style={{ width: '1px', height: '1px' }} // SVG origin is top-left of canvas
    >
      <defs>
        <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="4" markerHeight="4" orient="auto-start-reverse">
          <path d="M 0 0 L 10 5 L 0 10 z" fill="currentColor" />
        </marker>
      </defs>

      {/* Existing connections */}
      {connections.map((conn) => {
        const start = coords[conn.from];
        const end = coords[conn.to];
        if (!start || !end) return null;

        // Calculate a slight curve. If ports are close, use a tighter curve.
        const dx = Math.abs(end.x - start.x);
        const dy = Math.abs(end.y - start.y);
        const distance = Math.sqrt(dx*dx + dy*dy);
        const curvature = Math.min(100, distance / 3);

        return (
          <g key={conn.id} className="connection-group">
            <path
              d={`M ${start.x} ${start.y} C ${start.x + curvature} ${start.y}, ${end.x - curvature} ${end.y}, ${end.x} ${end.y}`}
              stroke={conn.color || '#3b82f6'}
              strokeWidth="2.5"
              fill="none"
              opacity="0.8"
              className="drop-shadow-sm transition-opacity hover:opacity-100"
            />
            {/* Thicker transparent helper for easier identification if we ever add hover interactions */}
            <path
              d={`M ${start.x} ${start.y} C ${start.x + curvature} ${start.y}, ${end.x - curvature} ${end.y}, ${end.x} ${end.y}`}
              stroke="transparent"
              strokeWidth="10"
              fill="none"
              className="pointer-events-auto cursor-help"
            />
          </g>
        );
      })}

      {/* Draft connection line (dashed) */}
      {draftStart && (
        <line
          x1={draftStart.x}
          y1={draftStart.y}
          x2={mousePos.x}
          y2={mousePos.y}
          stroke="#3b82f6"
          strokeWidth="2"
          strokeDasharray="5 3"
          opacity="0.6"
        />
      )}
    </svg>
  );
}
