"use client";

import * as React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { X } from "lucide-react";
import { cn } from "@/lib/utils";

const ResizableDialog = DialogPrimitive.Root;

const ResizableDialogTrigger = DialogPrimitive.Trigger;

const ResizableDialogPortal = DialogPrimitive.Portal;

const ResizableDialogClose = DialogPrimitive.Close;

const ResizableDialogOverlay = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Overlay>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
  <DialogPrimitive.Overlay
    ref={ref}
    className={cn(
      "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
      className
    )}
    {...props}
  />
));
ResizableDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;

interface ResizableDialogContentProps
  extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
  minWidth?: number;
  minHeight?: number;
  maxWidth?: number;
  maxHeight?: number;
  defaultWidth?: number;
  defaultHeight?: number;
  modalId?: string; // localStorage 저장용 고유 ID
  userId?: string; // 사용자별 저장용
}

const ResizableDialogContent = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Content>,
  ResizableDialogContentProps
>(
  (
    {
      className,
      children,
      minWidth = 400,
      minHeight = 300,
      maxWidth = 1400,
      maxHeight = 900,
      defaultWidth = 600,
      defaultHeight = 500,
      modalId,
      userId = "guest",
      style: userStyle,
      ...props
    },
    ref
  ) => {
    const contentRef = React.useRef<HTMLDivElement>(null);
    
    // 고정된 ID 생성 (한번 생성되면 컴포넌트 생명주기 동안 유지)
    const stableIdRef = React.useRef<string | null>(null);
    
    if (!stableIdRef.current) {
      if (modalId) {
        stableIdRef.current = modalId;
      } else {
        // className 기반 ID 생성
        if (className) {
          const hash = className.split('').reduce((acc, char) => {
            return ((acc << 5) - acc) + char.charCodeAt(0);
          }, 0);
          stableIdRef.current = `modal-${Math.abs(hash).toString(36)}`;
        } else if (userStyle) {
          // userStyle 기반 ID 생성
          const styleStr = JSON.stringify(userStyle);
          const hash = styleStr.split('').reduce((acc, char) => {
            return ((acc << 5) - acc) + char.charCodeAt(0);
          }, 0);
          stableIdRef.current = `modal-${Math.abs(hash).toString(36)}`;
        } else {
          // 기본 ID
          stableIdRef.current = 'modal-default';
        }
      }
    }
    
    const effectiveModalId = stableIdRef.current;
    
    // 실제 렌더링된 크기를 감지하여 초기 크기로 사용
    const getInitialSize = React.useCallback(() => {
      if (typeof window === 'undefined') return { width: defaultWidth, height: defaultHeight };
      
      // 1순위: userStyle에서 크기 추출 (화면관리에서 지정한 크기 - 항상 초기값으로 사용)
      if (userStyle) {
        const styleWidth = typeof userStyle.width === 'string' 
          ? parseInt(userStyle.width) 
          : userStyle.width;
        const styleHeight = typeof userStyle.height === 'string' 
          ? parseInt(userStyle.height) 
          : userStyle.height;
        
        if (styleWidth && styleHeight) {
          return {
            width: Math.max(minWidth, Math.min(maxWidth, styleWidth)),
            height: Math.max(minHeight, Math.min(maxHeight, styleHeight)),
          };
        }
      }
      
      // 2순위: 현재 렌더링된 크기 사용
      if (contentRef.current) {
        const rect = contentRef.current.getBoundingClientRect();
        if (rect.width > 0 && rect.height > 0) {
          return {
            width: Math.max(minWidth, Math.min(maxWidth, rect.width)),
            height: Math.max(minHeight, Math.min(maxHeight, rect.height)),
          };
        }
      }
      
      // 3순위: defaultWidth/defaultHeight 사용
      return { width: defaultWidth, height: defaultHeight };
    }, [defaultWidth, defaultHeight, minWidth, minHeight, maxWidth, maxHeight, userStyle]);

    const [size, setSize] = React.useState(getInitialSize);
    const [isResizing, setIsResizing] = React.useState(false);
    const [resizeDirection, setResizeDirection] = React.useState<string>("");
    const [isInitialized, setIsInitialized] = React.useState(false);

    // 모달이 열릴 때 초기 크기 설정 (localStorage 우선, 없으면 화면관리 설정)
    React.useEffect(() => {
      if (!isInitialized) {
        const initialSize = getInitialSize();
        
        // localStorage에서 저장된 크기가 있는지 확인
        if (effectiveModalId && typeof window !== 'undefined') {
          try {
            const storageKey = `modal_size_${effectiveModalId}_${userId}`;
            const saved = localStorage.getItem(storageKey);
            
            if (saved) {
              const parsed = JSON.parse(saved);
              // 저장된 크기가 있으면 그것을 사용 (사용자가 이전에 리사이즈한 크기)
              const restoredSize = {
                width: Math.max(minWidth, Math.min(maxWidth, parsed.width || initialSize.width)),
                height: Math.max(minHeight, Math.min(maxHeight, parsed.height || initialSize.height)),
              };
              setSize(restoredSize);
              setIsInitialized(true);
              return;
            }
          } catch (error) {
            console.error("모달 크기 복원 실패:", error);
          }
        }
        
        // 저장된 크기가 없으면 초기 크기 사용 (화면관리 설정 크기)
        setSize(initialSize);
        setIsInitialized(true);
      }
    }, [isInitialized, getInitialSize, effectiveModalId, userId, minWidth, maxWidth, minHeight, maxHeight]);

    const startResize = (direction: string) => (e: React.MouseEvent) => {
      e.preventDefault();
      e.stopPropagation();
      setIsResizing(true);
      setResizeDirection(direction);

      const startX = e.clientX;
      const startY = e.clientY;
      const startWidth = size.width;
      const startHeight = size.height;

      const handleMouseMove = (moveEvent: MouseEvent) => {
        const deltaX = moveEvent.clientX - startX;
        const deltaY = moveEvent.clientY - startY;

        let newWidth = startWidth;
        let newHeight = startHeight;

        if (direction.includes("e")) {
          newWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + deltaX));
        }
        if (direction.includes("w")) {
          newWidth = Math.max(minWidth, Math.min(maxWidth, startWidth - deltaX));
        }
        if (direction.includes("s")) {
          newHeight = Math.max(minHeight, Math.min(maxHeight, startHeight + deltaY));
        }
        if (direction.includes("n")) {
          newHeight = Math.max(minHeight, Math.min(maxHeight, startHeight - deltaY));
        }

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

      const handleMouseUp = () => {
        setIsResizing(false);
        setResizeDirection("");
        document.removeEventListener("mousemove", handleMouseMove);
        document.removeEventListener("mouseup", handleMouseUp);
        
        // localStorage에 크기 저장 (리사이즈 후 새로고침해도 유지)
        if (effectiveModalId && typeof window !== 'undefined') {
          try {
            const storageKey = `modal_size_${effectiveModalId}_${userId}`;
            const currentSize = { width: size.width, height: size.height };
            localStorage.setItem(storageKey, JSON.stringify(currentSize));
          } catch (error) {
            console.error("모달 크기 저장 실패:", error);
          }
        }
      };

      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);
    };

    return (
      <ResizableDialogPortal>
        <ResizableDialogOverlay />
        <DialogPrimitive.Content
          ref={ref}
          {...props}
          className={cn(
            "fixed left-[50%] top-[50%] z-50 translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
            isResizing && "select-none",
            className
          )}
          style={{
            ...userStyle,
            width: `${size.width}px`,
            height: `${size.height}px`,
            maxWidth: "95vw",
            maxHeight: "95vh",
            minWidth: `${minWidth}px`,
            minHeight: `${minHeight}px`,
          }}
        >
          <div ref={contentRef} className="flex flex-col h-full overflow-hidden">
            {children}
          </div>

          {/* 리사이즈 핸들 */}
          {/* 오른쪽 */}
          <div
            className="absolute right-0 top-0 h-full w-2 cursor-ew-resize hover:bg-primary/20 transition-colors"
            onMouseDown={startResize("e")}
          />
          {/* 아래 */}
          <div
            className="absolute bottom-0 left-0 w-full h-2 cursor-ns-resize hover:bg-primary/20 transition-colors"
            onMouseDown={startResize("s")}
          />
          {/* 오른쪽 아래 */}
          <div
            className="absolute right-0 bottom-0 w-4 h-4 cursor-nwse-resize hover:bg-primary/30 transition-colors"
            onMouseDown={startResize("se")}
          />
          {/* 왼쪽 */}
          <div
            className="absolute left-0 top-0 h-full w-2 cursor-ew-resize hover:bg-primary/20 transition-colors"
            onMouseDown={startResize("w")}
          />
          {/* 위 */}
          <div
            className="absolute top-0 left-0 w-full h-2 cursor-ns-resize hover:bg-primary/20 transition-colors"
            onMouseDown={startResize("n")}
          />
          {/* 왼쪽 아래 */}
          <div
            className="absolute left-0 bottom-0 w-4 h-4 cursor-nesw-resize hover:bg-primary/30 transition-colors"
            onMouseDown={startResize("sw")}
          />
          {/* 오른쪽 위 */}
          <div
            className="absolute right-0 top-0 w-4 h-4 cursor-nesw-resize hover:bg-primary/30 transition-colors"
            onMouseDown={startResize("ne")}
          />
          {/* 왼쪽 위 */}
          <div
            className="absolute left-0 top-0 w-4 h-4 cursor-nwse-resize hover:bg-primary/30 transition-colors"
            onMouseDown={startResize("nw")}
          />

          <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
            <X className="h-4 w-4" />
            <span className="sr-only">Close</span>
          </DialogPrimitive.Close>
        </DialogPrimitive.Content>
      </ResizableDialogPortal>
    );
  }
);
ResizableDialogContent.displayName = DialogPrimitive.Content.displayName;

const ResizableDialogHeader = ({
  className,
  ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
  <div
    className={cn(
      "flex flex-col space-y-1.5 text-center sm:text-left flex-shrink-0",
      className
    )}
    {...props}
  />
);
ResizableDialogHeader.displayName = "ResizableDialogHeader";

const ResizableDialogFooter = ({
  className,
  ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
  <div
    className={cn(
      "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 flex-shrink-0",
      className
    )}
    {...props}
  />
);
ResizableDialogFooter.displayName = "ResizableDialogFooter";

const ResizableDialogTitle = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Title>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...props }, ref) => (
  <DialogPrimitive.Title
    ref={ref}
    className={cn(
      "text-lg font-semibold leading-none tracking-tight",
      className
    )}
    {...props}
  />
));
ResizableDialogTitle.displayName = DialogPrimitive.Title.displayName;

const ResizableDialogDescription = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Description>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
>(({ className, ...props }, ref) => (
  <DialogPrimitive.Description
    ref={ref}
    className={cn("text-sm text-muted-foreground", className)}
    {...props}
  />
));
ResizableDialogDescription.displayName =
  DialogPrimitive.Description.displayName;

export {
  ResizableDialog,
  ResizableDialogPortal,
  ResizableDialogOverlay,
  ResizableDialogClose,
  ResizableDialogTrigger,
  ResizableDialogContent,
  ResizableDialogHeader,
  ResizableDialogFooter,
  ResizableDialogTitle,
  ResizableDialogDescription,
};

