"use client";

import React, { useMemo, useSyncExternalStore } from "react";
import { ComponentData, WebType, WidgetComponent } from "@/types/screen";
import { DynamicComponentRenderer } from "@/lib/registry/DynamicComponentRenderer";
import {
  Database,
  Type,
  Hash,
  List,
  AlignLeft,
  CheckSquare,
  Radio,
  Calendar,
  Code,
  Building,
  File,
} from "lucide-react";
import { useSplitPanel } from "@/lib/registry/components/split-panel-layout/SplitPanelContext";
import {
  subscribe as canvasSplitSubscribe,
  getSnapshot as canvasSplitGetSnapshot,
  getServerSnapshot as canvasSplitGetServerSnapshot,
  subscribeDom as canvasSplitSubscribeDom,
} from "@/lib/registry/components/v2-split-line/canvasSplitStore";
import { useScreenMultiLang } from "@/contexts/ScreenMultiLangContext";

// 컴포넌트 렌더러들 자동 등록
import "@/lib/registry/components";

interface RealtimePreviewProps {
  component: ComponentData;
  isSelected?: boolean;
  isDesignMode?: boolean; // 편집 모드 여부
  onClick?: (e?: React.MouseEvent) => void;
  onDoubleClick?: (e?: React.MouseEvent) => void; // 더블클릭 핸들러 추가
  onDragStart?: (e: React.DragEvent) => void;
  onDragEnd?: () => void;
  onGroupToggle?: (groupId: string) => void; // 그룹 접기/펼치기
  children?: React.ReactNode; // 그룹 내 자식 컴포넌트들
  selectedScreen?: any;
  onZoneComponentDrop?: (e: React.DragEvent, zoneId: string, layoutId: string) => void; // 존별 드롭 핸들러
  onZoneClick?: (zoneId: string) => void; // 존 클릭 핸들러
  onConfigChange?: (config: any) => void; // 설정 변경 핸들러
  onUpdateComponent?: (updatedComponent: any) => void; // 🆕 컴포넌트 업데이트 콜백
  onSelectTabComponent?: (tabId: string, compId: string, comp: any) => void; // 🆕 탭 내부 컴포넌트 선택 콜백
  selectedTabComponentId?: string; // 🆕 선택된 탭 컴포넌트 ID
  onSelectPanelComponent?: (panelSide: "left" | "right", compId: string, comp: any) => void; // 🆕 분할 패널 내부 컴포넌트 선택 콜백
  selectedPanelComponentId?: string; // 🆕 선택된 분할 패널 컴포넌트 ID
  onNestedPanelSelect?: (splitPanelId: string, panelSide: "left" | "right", compId: string, comp: any) => void;
  onResize?: (componentId: string, newSize: { width: number; height: number }) => void; // 🆕 리사이즈 콜백

  // 버튼 액션을 위한 props
  screenId?: number;
  tableName?: string;
  userId?: string; // 🆕 현재 사용자 ID
  userName?: string; // 🆕 현재 사용자 이름
  companyCode?: string; // 🆕 현재 사용자의 회사 코드
  menuObjid?: number; // 🆕 메뉴 OBJID (코드/카테고리 스코프용)
  selectedRowsData?: any[];
  onSelectedRowsChange?: (selectedRows: any[], selectedRowsData: any[]) => void;
  flowSelectedData?: any[];
  flowSelectedStepId?: number | null;
  onFlowSelectedDataChange?: (selectedData: any[], stepId: number | null) => void;
  refreshKey?: number;
  onRefresh?: () => void;
  flowRefreshKey?: number;
  onFlowRefresh?: () => void;

  // 폼 데이터 관련 props
  formData?: Record<string, any>;
  onFormDataChange?: (fieldName: string, value: any) => void;

  // 테이블 정렬 정보
  sortBy?: string;
  sortOrder?: "asc" | "desc";
  columnOrder?: string[];

  // 🆕 조건부 컨테이너 높이 변화 콜백
  onHeightChange?: (componentId: string, newHeight: number) => void;
  
  // 🆕 조건부 비활성화 상태
  conditionalDisabled?: boolean;
}

// 동적 위젯 타입 아이콘 (레지스트리에서 조회)
const getWidgetIcon = (widgetType: WebType | undefined): React.ReactNode => {
  if (!widgetType) return <Type className="h-3 w-3" />;

  const iconMap: Record<string, React.ReactNode> = {
    text: <span className="text-xs">Aa</span>,
    number: <Hash className="h-3 w-3" />,
    decimal: <Hash className="h-3 w-3" />,
    date: <Calendar className="h-3 w-3" />,
    datetime: <Calendar className="h-3 w-3" />,
    select: <List className="h-3 w-3" />,
    dropdown: <List className="h-3 w-3" />,
    textarea: <AlignLeft className="h-3 w-3" />,
    boolean: <CheckSquare className="h-3 w-3" />,
    checkbox: <CheckSquare className="h-3 w-3" />,
    radio: <Radio className="h-3 w-3" />,
    code: <Code className="h-3 w-3" />,
    entity: <Building className="h-3 w-3" />,
    file: <File className="h-3 w-3" />,
    email: <span className="text-xs">@</span>,
    tel: <span className="text-xs">☎</span>,
    button: <span className="text-xs">BTN</span>,
  };

  return iconMap[widgetType] || <Type className="h-3 w-3" />;
};

const RealtimePreviewDynamicComponent: React.FC<RealtimePreviewProps> = ({
  component,
  isSelected = false,
  isDesignMode = true, // 기본값은 편집 모드
  onClick,
  onDoubleClick,
  onDragStart,
  onDragEnd,
  onGroupToggle,
  children,
  selectedScreen,
  onZoneComponentDrop,
  onZoneClick,
  onConfigChange,
  screenId,
  tableName,
  userId, // 🆕 사용자 ID
  userName, // 🆕 사용자 이름
  companyCode, // 🆕 회사 코드
  menuObjid, // 🆕 메뉴 OBJID
  selectedRowsData,
  onSelectedRowsChange,
  flowSelectedData,
  flowSelectedStepId,
  onFlowSelectedDataChange,
  refreshKey,
  onRefresh,
  sortBy,
  sortOrder,
  columnOrder,
  flowRefreshKey,
  onFlowRefresh,
  formData,
  onFormDataChange,
  onHeightChange, // 🆕 조건부 컨테이너 높이 변화 콜백
  conditionalDisabled, // 🆕 조건부 비활성화 상태
  onUpdateComponent, // 🆕 컴포넌트 업데이트 콜백
  onSelectTabComponent, // 🆕 탭 내부 컴포넌트 선택 콜백
  selectedTabComponentId, // 🆕 선택된 탭 컴포넌트 ID
  onSelectPanelComponent, // 🆕 분할 패널 내부 컴포넌트 선택 콜백
  selectedPanelComponentId, // 🆕 선택된 분할 패널 컴포넌트 ID
  onNestedPanelSelect,
  onResize, // 🆕 리사이즈 콜백
}) => {
  // 🆕 화면 다국어 컨텍스트
  const { getTranslatedText } = useScreenMultiLang();
  
  const [actualHeight, setActualHeight] = React.useState<number | null>(null);
  const contentRef = React.useRef<HTMLDivElement>(null);
  const lastUpdatedHeight = React.useRef<number | null>(null);
  
  // 🆕 리사이즈 상태
  const [isResizing, setIsResizing] = React.useState(false);
  const [resizeSize, setResizeSize] = React.useState<{ width: number; height: number } | null>(null);
  const rafRef = React.useRef<number | null>(null);
  
  // 🆕 size가 업데이트되면 resizeSize 초기화 (레이아웃 상태가 props에 반영되었음)
  React.useEffect(() => {
    if (resizeSize && !isResizing) {
      // component.size가 resizeSize와 같아지면 resizeSize 초기화
      if (component.size?.width === resizeSize.width && component.size?.height === resizeSize.height) {
        setResizeSize(null);
      }
    }
  }, [component.size?.width, component.size?.height, resizeSize, isResizing]);
  
  // 10px 단위 스냅 함수
  const snapTo10 = (value: number) => Math.round(value / 10) * 10;
  
  // 🆕 리사이즈 핸들러
  const handleResizeStart = React.useCallback(
    (e: React.MouseEvent, direction: "e" | "s" | "se") => {
      e.stopPropagation();
      e.preventDefault();
      
      const startMouseX = e.clientX;
      const startMouseY = e.clientY;
      const startWidth = component.size?.width || 200;
      const startHeight = component.size?.height || 100;
      
      setIsResizing(true);
      setResizeSize({ width: startWidth, height: startHeight });

      const handleMouseMove = (moveEvent: MouseEvent) => {
        if (rafRef.current) {
          cancelAnimationFrame(rafRef.current);
        }
        
        rafRef.current = requestAnimationFrame(() => {
          const deltaX = moveEvent.clientX - startMouseX;
          const deltaY = moveEvent.clientY - startMouseY;
          
          let newWidth = startWidth;
          let newHeight = startHeight;
          
          if (direction === "e" || direction === "se") {
            newWidth = snapTo10(Math.max(50, startWidth + deltaX));
          }
          if (direction === "s" || direction === "se") {
            newHeight = snapTo10(Math.max(20, startHeight + deltaY));
          }
          
          setResizeSize({ width: newWidth, height: newHeight });
        });
      };

      const handleMouseUp = (upEvent: MouseEvent) => {
        document.removeEventListener("mousemove", handleMouseMove);
        document.removeEventListener("mouseup", handleMouseUp);
        
        if (rafRef.current) {
          cancelAnimationFrame(rafRef.current);
          rafRef.current = null;
        }
        
        const deltaX = upEvent.clientX - startMouseX;
        const deltaY = upEvent.clientY - startMouseY;
        
        let newWidth = startWidth;
        let newHeight = startHeight;
        
        if (direction === "e" || direction === "se") {
          newWidth = snapTo10(Math.max(50, startWidth + deltaX));
        }
        if (direction === "s" || direction === "se") {
          newHeight = snapTo10(Math.max(20, startHeight + deltaY));
        }
        
        // 🆕 리사이즈 상태는 유지한 채로 크기 변경 콜백 호출
        // resizeSize는 null로 설정하지 않고 마지막 크기 유지
        // (component.size가 업데이트되면 자연스럽게 올바른 크기 표시)
        
        // 🆕 크기 변경 콜백 호출하여 레이아웃 상태 업데이트
        if (onResize) {
          onResize(component.id, { width: newWidth, height: newHeight });
        }
        
        // 🆕 리사이즈 플래그만 해제 (resizeSize는 마지막 크기 유지)
        setIsResizing(false);
      };

      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);
    },
    [component.id, component.size, onResize]
  );

  // 플로우 위젯의 실제 높이 측정
  React.useEffect(() => {
    const isFlowWidget = component.type === "component" && (component as any).componentType === "flow-widget";

    if (isFlowWidget && contentRef.current) {
      const measureHeight = () => {
        if (contentRef.current) {
          // getBoundingClientRect()로 실제 렌더링된 높이 측정
          const rect = contentRef.current.getBoundingClientRect();
          const measured = rect.height;

          // scrollHeight도 함께 확인하여 더 큰 값 사용
          const scrollHeight = contentRef.current.scrollHeight;
          const rawHeight = Math.max(measured, scrollHeight);

          // 40px 단위로 올림
          const finalHeight = Math.ceil(rawHeight / 40) * 40;

          if (finalHeight > 0 && Math.abs(finalHeight - (actualHeight || 0)) > 10) {
            setActualHeight(finalHeight);

            // 컴포넌트의 실제 size.height도 업데이트 (중복 업데이트 방지)
            if (onConfigChange && finalHeight !== lastUpdatedHeight.current && finalHeight !== component.size?.height) {
              lastUpdatedHeight.current = finalHeight;
              // size는 별도 속성이므로 직접 업데이트
              const event = new CustomEvent("updateComponentSize", {
                detail: {
                  componentId: component.id,
                  height: finalHeight,
                },
              });
              window.dispatchEvent(event);
            }
          }
        }
      };

      // 초기 측정 (렌더링 완료 후)
      const initialTimer = setTimeout(() => {
        measureHeight();
      }, 100);

      // 추가 측정 (데이터 로딩 완료 대기)
      const delayedTimer = setTimeout(() => {
        measureHeight();
      }, 500);

      // 스텝 클릭 등으로 높이가 변경될 때를 위한 추가 측정
      const extendedTimer = setTimeout(() => {
        measureHeight();
      }, 1000);

      // ResizeObserver로 크기 변화 감지 (스텝 클릭 시 데이터 테이블 펼쳐짐)
      const resizeObserver = new ResizeObserver(() => {
        // 약간의 지연을 두고 측정 (DOM 업데이트 완료 대기)
        setTimeout(() => {
          measureHeight();
        }, 100);
      });

      resizeObserver.observe(contentRef.current);

      return () => {
        clearTimeout(initialTimer);
        clearTimeout(delayedTimer);
        clearTimeout(extendedTimer);
        resizeObserver.disconnect();
      };
    }
  }, [component.type, component.id, actualHeight, component.size?.height, onConfigChange]);
  const { id, type, position, size, style: componentStyle } = component;

  // 선택 상태에 따른 스타일 (z-index 낮춤 - 패널과 모달보다 아래)
  const selectionStyle = isSelected
    ? {
        outline: "2px solid rgb(59, 130, 246)",
        outlineOffset: "0px", // 스크롤 방지를 위해 0으로 설정
        zIndex: 20,
      }
    : {};

  // 컴포넌트 기본 스타일 - 레이아웃은 항상 맨 아래
  // 🔥 모든 컴포넌트를 픽셀 기준으로 통일 (스케일로만 조정)
  const getWidth = () => {
    // 모든 컴포넌트는 size.width 픽셀 사용 (table-list 포함)
    const width = `${size?.width || 100}px`;
    return width;
  };

  const getHeight = () => {
    // 🆕 조건부 컨테이너는 높이를 자동으로 설정 (내용물에 따라 자동 조정)
    const isConditionalContainer = (component as any).componentType === "conditional-container";
    if (isConditionalContainer && !isDesignMode) {
      return "auto"; // 런타임에서는 내용물 높이에 맞춤
    }

    // 플로우 위젯의 경우 측정된 높이 사용
    const isFlowWidget = component.type === "component" && (component as any).componentType === "flow-widget";
    if (isFlowWidget && actualHeight) {
      return `${actualHeight}px`;
    }

    // 런타임 모드에서 컴포넌트 타입별 높이 처리
    if (!isDesignMode) {
      const compType = (component as any).componentType || component.componentConfig?.type || "";
      // 레이아웃 계열: 부모 래퍼를 꽉 채움 (ResponsiveGridRenderer가 % 높이 관리)
      const fillParentTypes = [
        "table-list", "v2-table-list",
        "split-panel-layout", "split-panel-layout2",
        "v2-split-panel-layout", "screen-split-panel",
        "v2-tab-container", "tab-container",
        "tabs-widget", "v2-tabs-widget",
      ];
      if (fillParentTypes.some(t => compType === t)) {
        return "100%";
      }
      const autoHeightTypes = [
        "table-search-widget", "v2-table-search-widget",
        "flow-widget",
      ];
      if (autoHeightTypes.some(t => compType === t || compType.includes(t))) {
        return "auto";
      }
    }

    // 1순위: size.height가 있으면 우선 사용
    if (size?.height && size.height > 0) {
      if (component.componentConfig?.type === "table-list") {
        return `${Math.max(size.height, 200)}px`;
      }
      return `${size.height}px`;
    }

    // 2순위: componentStyle.height (컴포넌트 정의에서 온 기본 스타일)
    if (componentStyle?.height) {
      return typeof componentStyle.height === "number" ? `${componentStyle.height}px` : componentStyle.height;
    }

    // 3순위: 기본값
    if (component.componentConfig?.type === "table-list") {
      return "200px";
    }

    // 기본 높이
    return "10px";
  };

  // layout 타입 컴포넌트인지 확인
  const isLayoutComponent = component.type === "layout" || (component.componentConfig as any)?.type?.includes("layout");

  // layout 컴포넌트는 component 객체에 style.height 추가
  const enhancedComponent = isLayoutComponent
    ? {
        ...component,
        style: {
          ...component.style,
          height: getHeight(),
        },
      }
    : component;

  // 기존 분할 패널 리사이즈 Context (레거시 split-panel-layout용)
  const splitPanelContext = useSplitPanel();

  // 캔버스 분할선 글로벌 스토어 (useSyncExternalStore로 직접 구독)
  const canvasSplit = useSyncExternalStore(canvasSplitSubscribe, canvasSplitGetSnapshot, canvasSplitGetServerSnapshot);

  const componentType = (component as any).componentType || "";
  const componentId = (component as any).componentId || "";
  const widgetType = (component as any).widgetType || "";

  const isButtonComponent =
    (type === "widget" && widgetType === "button") ||
    (type === "component" &&
      (["button-primary", "button-secondary", "v2-button-primary"].includes(componentType) ||
        ["button-primary", "button-secondary", "v2-button-primary"].includes(componentId)));

  // 레거시 분할 패널용 refs
  const initialPanelRatioRef = React.useRef<number | null>(null);
  const initialPanelIdRef = React.useRef<string | null>(null);
  const isInLeftPanelRef = React.useRef<boolean | null>(null);

  // 캔버스 분할선 좌/우 판정 (한 번만)
  const canvasSplitSideRef = React.useRef<"left" | "right" | null>(null);
  // 스코프 체크 캐시 (DOM 쿼리 최소화)
  const myScopeIdRef = React.useRef<string | null>(null);

  const calculateSplitAdjustedPosition = () => {
    const isSplitLineComponent =
      type === "component" && componentType === "v2-split-line";

    if (isSplitLineComponent) {
      return { adjustedPositionX: position.x, adjustedWidth: null, isOnSplitPanel: false, isDraggingSplitPanel: false };
    }

    // === 1. 캔버스 분할선 (글로벌 스토어) ===
    if (canvasSplit.active && canvasSplit.canvasWidth > 0 && canvasSplit.scopeId) {
      if (myScopeIdRef.current === null) {
        const el = document.getElementById(`component-${id}`);
        const container = el?.closest("[data-screen-runtime]");
        myScopeIdRef.current = container?.getAttribute("data-split-scope") || "__none__";
      }
      if (myScopeIdRef.current !== canvasSplit.scopeId) {
        return { adjustedPositionX: position.x, adjustedWidth: null, isOnSplitPanel: false, isDraggingSplitPanel: false };
      }
      const { initialDividerX, currentDividerX, canvasWidth, isDragging: splitDragging } = canvasSplit;
      const delta = currentDividerX - initialDividerX;

      if (canvasSplitSideRef.current === null) {
        const origW = size?.width || 100;
        const componentCenterX = position.x + (origW / 2);
        canvasSplitSideRef.current = componentCenterX < initialDividerX ? "left" : "right";
      }

      if (Math.abs(delta) < 1) {
        return { adjustedPositionX: position.x, adjustedWidth: null, isOnSplitPanel: true, isDraggingSplitPanel: splitDragging };
      }

      // 영역별 비례 스케일링: 스플릿선이 벽 역할 → 절대 넘어가지 않음
      const origW = size?.width || 100;
      const GAP = 4;
      let adjustedX: number;
      let adjustedW: number;

      if (canvasSplitSideRef.current === "left") {
        const initialZoneWidth = initialDividerX;
        const currentZoneWidth = Math.max(20, currentDividerX - GAP);
        const scale = initialZoneWidth > 0 ? currentZoneWidth / initialZoneWidth : 1;
        adjustedX = position.x * scale;
        adjustedW = origW * scale;
        if (adjustedX + adjustedW > currentDividerX - GAP) {
          adjustedW = currentDividerX - GAP - adjustedX;
        }
      } else {
        const initialRightWidth = canvasWidth - initialDividerX;
        const currentRightWidth = Math.max(20, canvasWidth - currentDividerX - GAP);
        const scale = initialRightWidth > 0 ? currentRightWidth / initialRightWidth : 1;
        const rightOffset = position.x - initialDividerX;
        adjustedX = currentDividerX + GAP + rightOffset * scale;
        adjustedW = origW * scale;
        if (adjustedX < currentDividerX + GAP) adjustedX = currentDividerX + GAP;
        if (adjustedX + adjustedW > canvasWidth) adjustedW = canvasWidth - adjustedX;
      }

      adjustedX = Math.max(0, adjustedX);
      adjustedW = Math.max(20, adjustedW);

      return { adjustedPositionX: adjustedX, adjustedWidth: adjustedW, isOnSplitPanel: true, isDraggingSplitPanel: splitDragging };
    }

    // === 2. 레거시 분할 패널 (Context) - 버튼 전용 ===
    const isSplitPanelComponent =
      type === "component" && ["split-panel-layout", "split-panel-layout2"].includes(componentType);

    if (isSplitPanelComponent) {
      return { adjustedPositionX: position.x, adjustedWidth: null, isOnSplitPanel: false, isDraggingSplitPanel: false };
    }

    if (!isButtonComponent) {
      return { adjustedPositionX: position.x, adjustedWidth: null, isOnSplitPanel: false, isDraggingSplitPanel: false };
    }

    const componentWidth = size?.width || 100;
    const componentHeight = size?.height || 40;

    const overlap = splitPanelContext.getOverlappingSplitPanel(position.x, position.y, componentWidth, componentHeight);

    if (!overlap) {
      if (initialPanelIdRef.current !== null) {
        initialPanelRatioRef.current = null;
        initialPanelIdRef.current = null;
        isInLeftPanelRef.current = null;
      }
      return { adjustedPositionX: position.x, adjustedWidth: null, isOnSplitPanel: false, isDraggingSplitPanel: false };
    }

    const { panel } = overlap;

    if (initialPanelIdRef.current !== overlap.panelId) {
      initialPanelRatioRef.current = panel.initialLeftWidthPercent;
      initialPanelIdRef.current = overlap.panelId;
      const initialDividerX = panel.x + (panel.width * panel.initialLeftWidthPercent) / 100;
      const componentCenterX = position.x + componentWidth / 2;
      isInLeftPanelRef.current = componentCenterX < initialDividerX;
    }

    const baseRatio = initialPanelRatioRef.current ?? panel.initialLeftWidthPercent;
    const initialDividerX = panel.x + (panel.width * baseRatio) / 100;
    const currentDividerX = panel.x + (panel.width * panel.leftWidthPercent) / 100;
    const dividerDelta = currentDividerX - initialDividerX;

    if (Math.abs(dividerDelta) < 1) {
      return { adjustedPositionX: position.x, adjustedWidth: null, isOnSplitPanel: true, isDraggingSplitPanel: panel.isDragging };
    }

    const adjustedX = isInLeftPanelRef.current ? position.x + dividerDelta : position.x;

    return {
      adjustedPositionX: adjustedX,
      adjustedWidth: null,
      isOnSplitPanel: true,
      isDraggingSplitPanel: panel.isDragging,
    };
  };

  const { adjustedPositionX, adjustedWidth: splitAdjustedWidth, isOnSplitPanel, isDraggingSplitPanel } = calculateSplitAdjustedPosition();

  const displayWidth = resizeSize ? `${resizeSize.width}px` : getWidth();
  const displayHeight = resizeSize ? `${resizeSize.height}px` : getHeight();

  const isSplitActive = canvasSplit.active && canvasSplit.scopeId && myScopeIdRef.current === canvasSplit.scopeId;

  const origWidth = size?.width || 100;
  const isSplitShrunk = splitAdjustedWidth !== null && splitAdjustedWidth < origWidth;

  // position wrapper에서 border 제거 (내부 컴포넌트가 자체적으로 border를 렌더링하는 경우)
  // - v2 수평 라벨 컴포넌트: DynamicComponentRenderer가 내부에서 처리
  // - 버튼 컴포넌트: buttonElementStyle에서 자체 border 적용
  const isV2HorizLabel = !!(
    componentStyle &&
    componentStyle.labelDisplay !== false && componentStyle.labelDisplay !== "false" &&
    (componentStyle.labelPosition === "left" || componentStyle.labelPosition === "right")
  );
  const needsStripBorder = isV2HorizLabel || isButtonComponent;
  const safeComponentStyle = needsStripBorder
    ? (() => {
        const { borderWidth, borderColor, borderStyle, border, ...rest } = componentStyle as any;
        return rest;
      })()
    : componentStyle;

  const baseStyle = isDesignMode ? {
    // 디자인 모드: 기존 절대 좌표 방식 그대로 유지
    left: `${adjustedPositionX}px`,
    top: `${position.y}px`,
    ...safeComponentStyle,
    width: splitAdjustedWidth !== null ? `${splitAdjustedWidth}px` : displayWidth,
    height: displayHeight,
    zIndex: component.type === "layout" ? 1 : position.z || 2,
    right: undefined,
    overflow: isSplitShrunk ? "hidden" as const : undefined,
    willChange: canvasSplit.isDragging && isSplitActive ? "left, width" as const : undefined,
    transition:
      isResizing ? "none" :
      isOnSplitPanel ? (isDraggingSplitPanel ? "none" : "left 0.15s ease-out, width 0.15s ease-out") : undefined,
  } : {
    // 런타임 모드: 부모(ResponsiveGridRenderer)가 위치/너비 관리
    ...safeComponentStyle,
    width: "100%",
    height: displayHeight,
    position: "relative" as const,
  };

  // 크기 정보는 필요시에만 디버깅 (개발 중 문제 발생 시 주석 해제)
  // if (component.id && isSelected) {
  //   console.log("📐 RealtimePreview baseStyle:", {
  //     componentId: component.id,
  //     componentType: (component as any).componentType || component.type,
  //     sizeWidth: size?.width,
  //     sizeHeight: size?.height,
  //   });
  // }

  // 🔍 DOM 렌더링 후 실제 크기 측정
  const innerDivRef = React.useRef<HTMLDivElement>(null);
  const outerDivRef = React.useRef<HTMLDivElement>(null);

  React.useEffect(() => {
    if (outerDivRef.current && innerDivRef.current) {
      const outerRect = outerDivRef.current.getBoundingClientRect();
      const innerRect = innerDivRef.current.getBoundingClientRect();
      // 크기 측정 완료
    }
  }, [id, component.label, (component as any).gridColumns, baseStyle.width]);

  const handleClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    onClick?.(e);
  };

  const handleDoubleClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    onDoubleClick?.(e);
  };

  const handleDragStart = (e: React.DragEvent) => {
    e.stopPropagation();
    onDragStart?.(e);
  };

  const handleDragEnd = () => {
    onDragEnd?.();
  };

  const splitAdjustedComp = React.useMemo(() => {
    if (isSplitShrunk && splitAdjustedWidth !== null) {
      return { ...enhancedComponent, size: { ...(enhancedComponent as any).size, width: Math.round(splitAdjustedWidth) } };
    }
    return enhancedComponent;
  }, [enhancedComponent, isSplitShrunk, splitAdjustedWidth]);

  // 드래그 중 DOM 직접 조작 (React 리렌더 없이 매 프레임 업데이트)
  React.useEffect(() => {
    const isSplitLine = type === "component" && componentType === "v2-split-line";
    if (isSplitLine) return;

    const unsubscribe = canvasSplitSubscribeDom((snap) => {
      if (!snap.isDragging || !snap.active || !snap.scopeId) return;
      if (myScopeIdRef.current !== snap.scopeId) return;
      const el = outerDivRef.current;
      if (!el) return;

      const origX = position.x;
      const oW = size?.width || 100;
      const { initialDividerX, currentDividerX, canvasWidth } = snap;
      const delta = currentDividerX - initialDividerX;
      if (Math.abs(delta) < 1) return;

      if (canvasSplitSideRef.current === null) {
        canvasSplitSideRef.current = (origX + oW / 2) < initialDividerX ? "left" : "right";
      }

      const GAP = 4;
      let nx: number, nw: number;
      if (canvasSplitSideRef.current === "left") {
        const scale = initialDividerX > 0 ? Math.max(20, currentDividerX - GAP) / initialDividerX : 1;
        nx = origX * scale;
        nw = oW * scale;
        if (nx + nw > currentDividerX - GAP) nw = currentDividerX - GAP - nx;
      } else {
        const irw = canvasWidth - initialDividerX;
        const crw = Math.max(20, canvasWidth - currentDividerX - GAP);
        const scale = irw > 0 ? crw / irw : 1;
        nx = currentDividerX + GAP + (origX - initialDividerX) * scale;
        nw = oW * scale;
        if (nx < currentDividerX + GAP) nx = currentDividerX + GAP;
        if (nx + nw > canvasWidth) nw = canvasWidth - nx;
      }
      nx = Math.max(0, nx);
      nw = Math.max(20, nw);

      el.style.left = `${nx}px`;
      el.style.width = `${Math.round(nw)}px`;
      el.style.overflow = nw < oW ? "hidden" : "";
    });
    return unsubscribe;
  }, [id, position.x, size?.width, type, componentType]);

  return (
    <div
      ref={outerDivRef}
      id={`component-${id}`}
      data-component-id={id}
      className={`${isDesignMode ? "absolute" : "relative"} cursor-pointer transition-all duration-200 ease-out`}
      style={{ ...baseStyle, ...selectionStyle }}
      onClick={handleClick}
      onDoubleClick={handleDoubleClick}
      draggable={isDesignMode} // 디자인 모드에서만 드래그 가능
      onDragStart={isDesignMode ? handleDragStart : undefined}
      onDragEnd={isDesignMode ? handleDragEnd : undefined}
    >
      {/* 동적 컴포넌트 렌더링 */}
      <div
        ref={(node) => {
          // 멀티 ref 처리
          innerDivRef.current = node;
          if (component.type === "component" && (component as any).componentType === "flow-widget") {
            (contentRef as any).current = node;
          }
        }}
        className="h-full overflow-visible"
        style={{ width: "100%", maxWidth: "100%" }}
      >
        <DynamicComponentRenderer
          component={splitAdjustedComp}
          isSelected={isSelected}
          isDesignMode={isDesignMode}
          isInteractive={!isDesignMode} // 편집 모드가 아닐 때만 인터랙티브
          onClick={onClick}
          onDragStart={onDragStart}
          onDragEnd={onDragEnd}
          children={children}
          selectedScreen={selectedScreen}
          onZoneComponentDrop={onZoneComponentDrop}
          onZoneClick={onZoneClick}
          onConfigChange={onConfigChange}
          screenId={screenId}
          tableName={tableName}
          userId={userId}
          userName={userName}
          companyCode={companyCode}
          menuObjid={menuObjid}
          selectedRowsData={selectedRowsData}
          onSelectedRowsChange={onSelectedRowsChange}
          flowSelectedData={flowSelectedData}
          flowSelectedStepId={flowSelectedStepId}
          onFlowSelectedDataChange={onFlowSelectedDataChange}
          refreshKey={refreshKey}
          onRefresh={onRefresh}
          flowRefreshKey={flowRefreshKey}
          onFlowRefresh={onFlowRefresh}
          formData={formData}
          onFormDataChange={onFormDataChange}
          sortBy={sortBy}
          sortOrder={sortOrder}
          columnOrder={columnOrder}
          onHeightChange={onHeightChange}
          conditionalDisabled={conditionalDisabled}
          onUpdateComponent={onUpdateComponent}
          onSelectTabComponent={onSelectTabComponent}
          selectedTabComponentId={selectedTabComponentId}
          onSelectPanelComponent={onSelectPanelComponent}
          selectedPanelComponentId={selectedPanelComponentId}
          onNestedPanelSelect={onNestedPanelSelect}
        />
      </div>

      {/* 선택된 컴포넌트 정보 표시 */}
      {isSelected && (
        <div className="bg-primary text-primary-foreground absolute -top-7 right-0 rounded-md px-2.5 py-1 text-xs font-medium shadow-sm">
          {type === "widget" && (
            <div className="flex items-center gap-1.5">
              {getWidgetIcon((component as WidgetComponent).widgetType)}
              <span>{(component as WidgetComponent).widgetType || "widget"}</span>
            </div>
          )}
          {type !== "widget" && (
            <div className="flex items-center gap-1.5">
              <span>{(() => {
                const ft = (component as any).componentConfig?.fieldType;
                if (ft) {
                  const labels: Record<string, string> = {
                    text: "텍스트", number: "숫자", textarea: "여러줄",
                    select: "셀렉트", category: "카테고리", entity: "엔티티",
                    numbering: "채번",
                  };
                  return labels[ft] || ft;
                }
                return (component as any).componentConfig?.type || componentType || type;
              })()}</span>
            </div>
          )}
        </div>
      )}

      {/* 🆕 리사이즈 가장자리 영역 - 선택된 컴포넌트 + 디자인 모드에서만 표시 */}
      {isSelected && isDesignMode && onResize && (
        <>
          {/* 오른쪽 가장자리 (너비 조절) */}
          <div
            className="absolute top-0 right-0 w-2 h-full cursor-ew-resize z-20 hover:bg-primary/10"
            onMouseDown={(e) => handleResizeStart(e, "e")}
          />
          {/* 아래 가장자리 (높이 조절) */}
          <div
            className="absolute bottom-0 left-0 w-full h-2 cursor-ns-resize z-20 hover:bg-primary/10"
            onMouseDown={(e) => handleResizeStart(e, "s")}
          />
          {/* 오른쪽 아래 모서리 (너비+높이 조절) */}
          <div
            className="absolute bottom-0 right-0 w-3 h-3 cursor-nwse-resize z-30 hover:bg-primary/20"
            onMouseDown={(e) => handleResizeStart(e, "se")}
          />
        </>
      )}
    </div>
  );
};

// 🔧 arePropsEqual 제거 - 기본 React.memo 사용 (디버깅용)
// component 객체가 새로 생성되면 자동으로 리렌더링됨
export const RealtimePreviewDynamic = React.memo(RealtimePreviewDynamicComponent);

// displayName 설정 (디버깅용)
RealtimePreviewDynamic.displayName = "RealtimePreviewDynamic";

// 기존 RealtimePreview와의 호환성을 위한 export
export { RealtimePreviewDynamic as RealtimePreview };
export default RealtimePreviewDynamic;
