import { useSearchParams } from '@remix-run/react';
import { useState, useEffect, MouseEvent, useRef } from 'react';

interface DraggableBoxProps {
  tag: string;
  initialX: number;
  initialY: number;
  className?: string;
  children?: React.ReactNode;
}

const DraggableBox = ({
  tag,
  initialX,
  initialY,
  className = "",
  children = ""
}: DraggableBoxProps) => {
  const [isDragging, setIsDragging] = useState(false);
  const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
  const [searchParams, setSearchParams] = useSearchParams();
  const dragRef = useRef<HTMLDivElement>(null);

  const xParam = `x${tag}`;
  const yParam = `y${tag}`;

  useEffect(() => {
    if (!searchParams.has(xParam) || !searchParams.has(yParam)) {
      const newParams = new URLSearchParams(searchParams);
      newParams.set(xParam, initialX.toString());
      newParams.set(yParam, initialY.toString());
      setSearchParams(newParams, { replace: true });
    }

    if (!isDragging) return;

    const handleMouseMove = (e: globalThis.MouseEvent) => {
      if (!dragRef.current?.parentElement) return;

      const parent = dragRef.current.parentElement;
      const parentRect = parent.getBoundingClientRect();
      const boxRect = dragRef.current.getBoundingClientRect();

      const relativeX = e.clientX - parentRect.left - dragOffset.x;
      const relativeY = e.clientY - parentRect.top - dragOffset.y;

      const maxX = parentRect.width - boxRect.width;
      const maxY = parentRect.height - boxRect.height;

      const newX = Math.max(0, Math.min(relativeX, maxX));
      const newY = Math.max(0, Math.min(relativeY, maxY));

      const newParams = new URLSearchParams(searchParams);
      newParams.set(xParam, newX.toString());
      newParams.set(yParam, newY.toString());
      setSearchParams(newParams, { replace: true });
    };

    const handleMouseUp = () => setIsDragging(false);

    window.addEventListener('mousemove', handleMouseMove);
    window.addEventListener('mouseup', handleMouseUp);

    return () => {
      window.removeEventListener('mousemove', handleMouseMove);
      window.removeEventListener('mouseup', handleMouseUp);
    };
  }, [isDragging, dragOffset, tag, searchParams, initialX, initialY]);

  const handleMouseDown = (e: MouseEvent) => {
    if (!dragRef.current?.parentElement) return;

    const parentRect = dragRef.current.parentElement.getBoundingClientRect();
    const currentX = parseInt(searchParams.get(xParam) || '0');
    const currentY = parseInt(searchParams.get(yParam) || '0');

    setDragOffset({
      x: e.clientX - parentRect.left - currentX,
      y: e.clientY - parentRect.top - currentY
    });
    setIsDragging(true);
  };

  return (
    <div
      ref={dragRef}
      className={`absolute cursor-move bg-red-500 rounded-full w-4 h-4 text-white shadow-lg ${className}`}
      style={{
        transform: `translate(${searchParams.get(xParam) || 0}px, ${searchParams.get(yParam) || 0}px)`,
        userSelect: 'none',
      }}
      onMouseDown={handleMouseDown}
    >
      {children}
    </div>
  );
};

export default DraggableBox;
