"use client";

import React, { useState, useRef, useEffect } from "react";
import { X, GripVertical } from "lucide-react";
import { cn } from "@/lib/utils";

interface FloatingPanelProps {
  id: string;
  title: string;
  children: React.ReactNode;
  isOpen: boolean;
  onClose: () => void;
  position?: "left" | "right" | "top" | "bottom";
  width?: number;
  height?: number;
  minWidth?: number;
  minHeight?: number;
  maxWidth?: number;
  maxHeight?: number;
  resizable?: boolean;
  draggable?: boolean;
  autoHeight?: boolean; // 자동 높이 조정 옵션
  className?: string;
}

export const FloatingPanel: React.FC<FloatingPanelProps> = ({
  id,
  title,
  children,
  isOpen,
  onClose,
  position = "right",
  width = 320,
  height = 400,
  minWidth = 280,
  minHeight = 300,
  maxWidth = 600,
  maxHeight = 1200, // 800 → 1200 (더 큰 패널 지원)
  resizable = true,
  draggable = true,
  autoHeight = true, // 자동 높이 조정 활성화 (컨텐츠 크기에 맞게)
  className,
}) => {
  const [panelSize, setPanelSize] = useState({ width, height });

  // props 변경 시 패널 크기 업데이트
  useEffect(() => {
    setPanelSize({ width, height });
  }, [width, height]);
  const [panelPosition, setPanelPosition] = useState({ x: 0, y: 0 });
  const [isDragging, setIsDragging] = useState(false);
  const [isResizing, setIsResizing] = useState(false);
  const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });

  const panelRef = useRef<HTMLDivElement>(null);
  const dragHandleRef = useRef<HTMLDivElement>(null);
  const contentRef = useRef<HTMLDivElement>(null);

  // 초기 위치 설정 (패널이 처음 열릴 때만)
  const [hasInitialized, setHasInitialized] = useState(false);

  useEffect(() => {
    if (isOpen && !hasInitialized && panelRef.current) {
      const viewportWidth = window.innerWidth;
      const viewportHeight = window.innerHeight;

      let initialX = 0;
      let initialY = 0;

      switch (position) {
        case "left":
          initialX = 20;
          initialY = 80;
          break;
        case "right":
          initialX = viewportWidth - panelSize.width - 20;
          initialY = 80;
          break;
        case "top":
          initialX = (viewportWidth - panelSize.width) / 2;
          initialY = 20;
          break;
        case "bottom":
          initialX = (viewportWidth - panelSize.width) / 2;
          initialY = viewportHeight - panelSize.height - 20;
          break;
      }

      setPanelPosition({ x: initialX, y: initialY });
      setHasInitialized(true);
    }

    // 패널이 닫힐 때 초기화 상태 리셋
    if (!isOpen) {
      setHasInitialized(false);
    }
  }, [isOpen, position, hasInitialized]);

  // 자동 높이 조정 기능
  useEffect(() => {
    if (!autoHeight || !contentRef.current || isResizing) return;

    const updateHeight = () => {
      if (!contentRef.current) return;

      // 일시적으로 높이 제한을 해제하여 실제 컨텐츠 높이 측정
      contentRef.current.style.maxHeight = "none";

      // 컨텐츠의 실제 높이 측정
      const contentHeight = contentRef.current.scrollHeight;
      const headerHeight = 60; // 헤더 높이
      const padding = 30; // 여유 공간 (좀 더 넉넉하게)

      const newHeight = Math.min(Math.max(minHeight, contentHeight + headerHeight + padding), maxHeight);

      // console.log(`🔧 패널 높이 자동 조정:`, {
      // panelId: id,
      // contentHeight,
      // calculatedHeight: newHeight,
      // currentHeight: panelSize.height,
      // willUpdate: Math.abs(panelSize.height - newHeight) > 10,
      // });

      // 현재 높이와 다르면 업데이트
      if (Math.abs(panelSize.height - newHeight) > 10) {
        setPanelSize((prev) => ({ ...prev, height: newHeight }));
      }
    };

    // 초기 높이 설정
    updateHeight();

    // ResizeObserver로 컨텐츠 크기 변화 감지
    const resizeObserver = new ResizeObserver((entries) => {
      // DOM 업데이트가 완료된 후에 높이 측정
      requestAnimationFrame(() => {
        setTimeout(updateHeight, 50); // 약간의 지연으로 렌더링 완료 후 측정
      });
    });

    resizeObserver.observe(contentRef.current);

    return () => {
      resizeObserver.disconnect();
    };
  }, [autoHeight, minHeight, maxHeight, isResizing, panelSize.height, children]);

  // 드래그 시작 - 성능 최적화
  const handleDragStart = (e: React.MouseEvent) => {
    if (!draggable) return;

    e.preventDefault(); // 기본 동작 방지로 딜레이 제거
    e.stopPropagation(); // 이벤트 버블링 방지

    setIsDragging(true);
    const rect = panelRef.current?.getBoundingClientRect();
    if (rect) {
      setDragOffset({
        x: e.clientX - rect.left,
        y: e.clientY - rect.top,
      });
    }
  };

  // 리사이즈 시작
  const handleResizeStart = (e: React.MouseEvent) => {
    if (!resizable) return;

    e.preventDefault();
    setIsResizing(true);
  };

  // 마우스 이동 처리 - 초고속 최적화
  useEffect(() => {
    if (!isDragging && !isResizing) return;

    const handleMouseMove = (e: MouseEvent) => {
      if (isDragging) {
        // 직접 DOM 조작으로 최고 성능
        if (panelRef.current) {
          const newX = e.clientX - dragOffset.x;
          const newY = e.clientY - dragOffset.y;

          panelRef.current.style.left = `${newX}px`;
          panelRef.current.style.top = `${newY}px`;

          // 상태는 throttle로 업데이트
          setPanelPosition({ x: newX, y: newY });
        }
      } else if (isResizing) {
        const newWidth = Math.max(minWidth, Math.min(maxWidth, e.clientX - panelPosition.x));
        const newHeight = Math.max(minHeight, Math.min(maxHeight, e.clientY - panelPosition.y));

        if (panelRef.current) {
          panelRef.current.style.width = `${newWidth}px`;
          panelRef.current.style.height = `${newHeight}px`;
        }

        setPanelSize({ width: newWidth, height: newHeight });
      }
    };

    const handleMouseUp = () => {
      setIsDragging(false);
      setIsResizing(false);
    };

    // 고성능 이벤트 리스너
    document.addEventListener("mousemove", handleMouseMove, {
      passive: true,
      capture: false,
    });
    document.addEventListener("mouseup", handleMouseUp, {
      passive: true,
      capture: false,
    });

    return () => {
      document.removeEventListener("mousemove", handleMouseMove);
      document.removeEventListener("mouseup", handleMouseUp);
    };
  }, [isDragging, isResizing, dragOffset.x, dragOffset.y, panelPosition.x, minWidth, maxWidth, minHeight, maxHeight]);

  if (!isOpen) return null;

  return (
    <div
      ref={panelRef}
      className={cn(
        "bg-card text-card-foreground fixed z-[100] rounded-lg border shadow-lg",
        isDragging ? "cursor-move shadow-2xl" : "transition-all duration-200 ease-in-out",
        isResizing && "cursor-se-resize",
        className,
      )}
      style={{
        left: `${panelPosition.x}px`,
        top: `${panelPosition.y}px`,
        width: `${panelSize.width}px`,
        height: `${panelSize.height}px`,
        transform: isDragging ? "scale(1.01)" : "scale(1)",
        transition: isDragging ? "none" : "transform 0.1s ease-out, box-shadow 0.1s ease-out",
        zIndex: isDragging ? 101 : 100,
      }}
    >
      {/* 헤더 */}
      <div
        ref={dragHandleRef}
        data-header="true"
        className="bg-muted/40 flex cursor-move items-center justify-between border-b px-4 py-3"
        onMouseDown={handleDragStart}
        style={{
          userSelect: "none",
          WebkitUserSelect: "none",
          MozUserSelect: "none",
          msUserSelect: "none",
        }}
      >
        <div className="flex items-center gap-2">
          <GripVertical className="text-muted-foreground h-4 w-4" />
          <h3 className="text-sm font-semibold">{title}</h3>
        </div>
        <button onClick={onClose} className="hover:bg-accent rounded-md p-1.5 transition-colors">
          <X className="h-4 w-4" />
        </button>
      </div>

      {/* 컨텐츠 */}
      <div
        ref={contentRef}
        className={autoHeight ? "flex-1 w-full overflow-hidden" : "flex-1 w-full overflow-y-auto overflow-x-hidden"}
        style={
          autoHeight
            ? {}
            : {
                maxHeight: `${panelSize.height - 60}px`, // 헤더 높이 제외
              }
        }
      >
        {children}
      </div>

      {/* 리사이즈 핸들 */}
      {resizable && !autoHeight && (
        <div className="absolute right-0 bottom-0 h-4 w-4 cursor-se-resize" onMouseDown={handleResizeStart}>
          <div className="bg-muted-foreground/40 absolute right-1 bottom-1 h-2 w-2 rounded-sm" />
        </div>
      )}
    </div>
  );
};

export default FloatingPanel;
