"use client";

import { useRef, useEffect, useState } from "react";
import { useDrop } from "react-dnd";
import { useReportDesigner } from "@/contexts/ReportDesignerContext";
import { ComponentConfig, WatermarkConfig } from "@/types/report";
import { CanvasComponent } from "./CanvasComponent";
import { Ruler } from "./Ruler";
import { v4 as uuidv4 } from "uuid";
import { getFullImageUrl } from "@/lib/api/client";

// mm를 px로 변환하는 고정 스케일 팩터 (화면 해상도와 무관하게 일정)
// A4 기준: 210mm x 297mm → 840px x 1188px
export const MM_TO_PX = 4;

// 워터마크 레이어 컴포넌트
interface WatermarkLayerProps {
  watermark: WatermarkConfig;
  canvasWidth: number;
  canvasHeight: number;
}

function WatermarkLayer({ watermark, canvasWidth, canvasHeight }: WatermarkLayerProps) {
  // 공통 스타일
  const baseStyle: React.CSSProperties = {
    position: "absolute",
    top: 0,
    left: 0,
    width: "100%",
    height: "100%",
    pointerEvents: "none",
    overflow: "hidden",
    zIndex: 1, // 컴포넌트보다 낮은 z-index
  };

  // 대각선 스타일
  if (watermark.style === "diagonal") {
    const rotation = watermark.rotation ?? -45;
    return (
      <div style={baseStyle}>
        <div
          className="absolute flex items-center justify-center"
          style={{
            top: "50%",
            left: "50%",
            transform: `translate(-50%, -50%) rotate(${rotation}deg)`,
            opacity: watermark.opacity,
            whiteSpace: "nowrap",
          }}
        >
          {watermark.type === "text" ? (
            <span
              style={{
                fontSize: `${watermark.fontSize || 48}px`,
                color: watermark.fontColor || "#cccccc",
                fontWeight: "bold",
                userSelect: "none",
              }}
            >
              {watermark.text || "WATERMARK"}
            </span>
          ) : (
            watermark.imageUrl && (
              <img
                src={getFullImageUrl(watermark.imageUrl)}
                alt="watermark"
                style={{
                  maxWidth: "50%",
                  maxHeight: "50%",
                  objectFit: "contain",
                }}
              />
            )
          )}
        </div>
      </div>
    );
  }

  // 중앙 스타일
  if (watermark.style === "center") {
    return (
      <div style={baseStyle}>
        <div
          className="absolute flex items-center justify-center"
          style={{
            top: "50%",
            left: "50%",
            transform: "translate(-50%, -50%)",
            opacity: watermark.opacity,
          }}
        >
          {watermark.type === "text" ? (
            <span
              style={{
                fontSize: `${watermark.fontSize || 48}px`,
                color: watermark.fontColor || "#cccccc",
                fontWeight: "bold",
                userSelect: "none",
              }}
            >
              {watermark.text || "WATERMARK"}
            </span>
          ) : (
            watermark.imageUrl && (
              <img
                src={getFullImageUrl(watermark.imageUrl)}
                alt="watermark"
                style={{
                  maxWidth: "50%",
                  maxHeight: "50%",
                  objectFit: "contain",
                }}
              />
            )
          )}
        </div>
      </div>
    );
  }

  // 타일 스타일
  if (watermark.style === "tile") {
    const rotation = watermark.rotation ?? -30;
    // 타일 간격 계산
    const tileSize = watermark.type === "text" ? (watermark.fontSize || 48) * 4 : 150;
    const cols = Math.ceil(canvasWidth / tileSize) + 2;
    const rows = Math.ceil(canvasHeight / tileSize) + 2;

    return (
      <div style={baseStyle}>
        <div
          style={{
            position: "absolute",
            top: "-50%",
            left: "-50%",
            width: "200%",
            height: "200%",
            display: "flex",
            flexWrap: "wrap",
            alignContent: "flex-start",
            transform: `rotate(${rotation}deg)`,
            opacity: watermark.opacity,
          }}
        >
          {Array.from({ length: rows * cols }).map((_, index) => (
            <div
              key={index}
              style={{
                width: `${tileSize}px`,
                height: `${tileSize}px`,
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
              }}
            >
              {watermark.type === "text" ? (
                <span
                  style={{
                    fontSize: `${watermark.fontSize || 24}px`,
                    color: watermark.fontColor || "#cccccc",
                    fontWeight: "bold",
                    userSelect: "none",
                    whiteSpace: "nowrap",
                  }}
                >
                  {watermark.text || "WATERMARK"}
                </span>
              ) : (
                watermark.imageUrl && (
                  <img
                    src={getFullImageUrl(watermark.imageUrl)}
                    alt="watermark"
                    style={{
                      width: `${tileSize * 0.6}px`,
                      height: `${tileSize * 0.6}px`,
                      objectFit: "contain",
                    }}
                  />
                )
              )}
            </div>
          ))}
        </div>
      </div>
    );
  }

  return null;
}

export function ReportDesignerCanvas() {
  const canvasRef = useRef<HTMLDivElement>(null);
  const {
    currentPageId,
    currentPage,
    components,
    addComponent,
    updateComponent,
    canvasWidth,
    canvasHeight,
    margins,
    selectComponent,
    selectMultipleComponents,
    selectedComponentId,
    selectedComponentIds,
    removeComponent,
    showGrid,
    gridSize,
    snapValueToGrid,
    alignmentGuides,
    copyComponents,
    pasteComponents,
    duplicateComponents,
    copyStyles,
    pasteStyles,
    fitSelectedToContent,
    undo,
    redo,
    showRuler,
    layoutConfig,
  } = useReportDesigner();

  // 드래그 영역 선택 (Marquee Selection) 상태
  const [isMarqueeSelecting, setIsMarqueeSelecting] = useState(false);
  const [marqueeStart, setMarqueeStart] = useState({ x: 0, y: 0 });
  const [marqueeEnd, setMarqueeEnd] = useState({ x: 0, y: 0 });
  // 클로저 문제 해결을 위한 refs (동기적으로 업데이트)
  const marqueeStartRef = useRef({ x: 0, y: 0 });
  const marqueeEndRef = useRef({ x: 0, y: 0 });
  const componentsRef = useRef(components);
  const selectMultipleRef = useRef(selectMultipleComponents);
  // 마퀴 선택 직후 click 이벤트 무시를 위한 플래그
  const justFinishedMarqueeRef = useRef(false);

  // refs 동기적 업데이트 (useEffect 대신 직접 할당)
  componentsRef.current = components;
  selectMultipleRef.current = selectMultipleComponents;

  const [{ isOver }, drop] = useDrop(() => ({
    accept: "component",
    drop: (item: { componentType: string }, monitor) => {
      if (!canvasRef.current) return;

      const offset = monitor.getClientOffset();
      const canvasRect = canvasRef.current.getBoundingClientRect();

      if (!offset) return;

      const x = offset.x - canvasRect.left;
      const y = offset.y - canvasRect.top;

      // 컴포넌트 타입별 기본 설정
      let width = 200;
      let height = 100;

      if (item.componentType === "table") {
        height = 200;
      } else if (item.componentType === "image") {
        width = 150;
        height = 150;
      } else if (item.componentType === "divider") {
        width = 300;
        height = 10; // 선 두께 + 여백 (선택/드래그를 위한 최소 높이)
      } else if (item.componentType === "signature") {
        width = 120;
        height = 70;
      } else if (item.componentType === "stamp") {
        width = 70;
        height = 70;
      } else if (item.componentType === "pageNumber") {
        width = 100;
        height = 30;
      } else if (item.componentType === "barcode") {
        width = 200;
        height = 80;
      } else if (item.componentType === "checkbox") {
        width = 150;
        height = 30;
      }

      // 여백을 px로 변환
      const marginTopPx = margins.top * MM_TO_PX;
      const marginLeftPx = margins.left * MM_TO_PX;
      const marginRightPx = margins.right * MM_TO_PX;
      const marginBottomPx = margins.bottom * MM_TO_PX;

      // 캔버스 경계 (px)
      const canvasWidthPx = canvasWidth * MM_TO_PX;
      const canvasHeightPx = canvasHeight * MM_TO_PX;

      // 드롭 위치 계산 (여백 내부로 제한)
      const rawX = x - 100;
      const rawY = y - 25;
      const minX = marginLeftPx;
      const minY = marginTopPx;
      const maxX = canvasWidthPx - marginRightPx - width;
      const maxY = canvasHeightPx - marginBottomPx - height;

      const boundedX = Math.min(Math.max(minX, rawX), maxX);
      const boundedY = Math.min(Math.max(minY, rawY), maxY);

      // 새 컴포넌트 생성 (Grid Snap 적용)
      const newComponent: ComponentConfig = {
        id: `comp_${uuidv4()}`,
        type: item.componentType,
        x: snapValueToGrid(boundedX),
        y: snapValueToGrid(boundedY),
        width: snapValueToGrid(width),
        height: snapValueToGrid(height),
        zIndex: components.length,
        fontSize: 13,
        fontFamily: "Malgun Gothic",
        fontWeight: "normal",
        fontColor: "#000000",
        backgroundColor: "transparent",
        borderWidth: 0,
        borderColor: "#cccccc",
        borderRadius: 5,
        textAlign: "left",
        padding: 10,
        visible: true,
        printable: true,
        // 이미지 전용
        ...(item.componentType === "image" && {
          imageUrl: "",
          objectFit: "contain" as const,
        }),
        // 구분선 전용
        ...(item.componentType === "divider" && {
          orientation: "horizontal" as const,
          lineStyle: "solid" as const,
          lineWidth: 1,
          lineColor: "#000000",
        }),
        // 서명란 전용
        ...(item.componentType === "signature" && {
          imageUrl: "",
          objectFit: "contain" as const,
          showLabel: true,
          labelText: "서명:",
          labelPosition: "left" as const,
          borderWidth: 0,
          borderColor: "#cccccc",
        }),
        // 도장란 전용
        ...(item.componentType === "stamp" && {
          imageUrl: "",
          objectFit: "contain" as const,
          showLabel: true,
          labelText: "(인)",
          labelPosition: "top" as const,
          personName: "",
          borderWidth: 0,
          borderColor: "#cccccc",
        }),
        // 페이지 번호 전용
        ...(item.componentType === "pageNumber" && {
          pageNumberFormat: "number" as const, // number, numberTotal, koreanNumber
          textAlign: "center" as const,
        }),
        // 카드 컴포넌트 전용
        ...(item.componentType === "card" && {
          width: 300,
          height: 180,
          cardTitle: "정보 카드",
          showCardTitle: true,
          cardItems: [
            { label: "항목1", value: "내용1", fieldName: "" },
            { label: "항목2", value: "내용2", fieldName: "" },
            { label: "항목3", value: "내용3", fieldName: "" },
          ],
          labelWidth: 80,
          showCardBorder: true,
          titleFontSize: 14,
          labelFontSize: 13,
          valueFontSize: 13,
          titleColor: "#1e40af",
          labelColor: "#374151",
          valueColor: "#000000",
          borderWidth: 1,
          borderColor: "#e5e7eb",
        }),
        // 계산 컴포넌트 전용
        ...(item.componentType === "calculation" && {
          width: 350,
          height: 120,
          calcItems: [
            { label: "공급가액", value: 0, operator: "+" as const, fieldName: "" },
            { label: "부가세 (10%)", value: 0, operator: "+" as const, fieldName: "" },
          ],
          resultLabel: "합계 금액",
          labelWidth: 120,
          labelFontSize: 13,
          valueFontSize: 13,
          resultFontSize: 16,
          labelColor: "#374151",
          valueColor: "#000000",
          resultColor: "#2563eb",
          showCalcBorder: false,
          numberFormat: "currency" as const,
          currencySuffix: "원",
          borderWidth: 0,
          borderColor: "#e5e7eb",
        }),
        // 테이블 전용
        ...(item.componentType === "table" && {
          queryId: undefined,
          tableColumns: [],
          headerBackgroundColor: "#f3f4f6",
          headerTextColor: "#111827",
          showBorder: true,
          rowHeight: 32,
        }),
        // 바코드 컴포넌트 전용
        ...(item.componentType === "barcode" && {
          barcodeType: "CODE128" as const,
          barcodeValue: "SAMPLE123",
          barcodeFieldName: "",
          showBarcodeText: true,
          barcodeColor: "#000000",
          barcodeBackground: "transparent",
          barcodeMargin: 10,
          qrErrorCorrectionLevel: "M" as const,
        }),
        // 체크박스 컴포넌트 전용
        ...(item.componentType === "checkbox" && {
          checkboxChecked: false,
          checkboxLabel: "항목",
          checkboxSize: 18,
          checkboxColor: "#2563eb",
          checkboxBorderColor: "#6b7280",
          checkboxLabelPosition: "right" as const,
        }),
      };

      addComponent(newComponent);
    },
    collect: (monitor) => ({
      isOver: monitor.isOver(),
    }),
  }));

  // 캔버스 클릭 시 선택 해제 (드래그 선택이 아닐 때만)
  const handleCanvasClick = (e: React.MouseEvent<HTMLDivElement>) => {
    // 마퀴 선택 직후의 click 이벤트는 무시
    if (justFinishedMarqueeRef.current) {
      justFinishedMarqueeRef.current = false;
      return;
    }
    if (e.target === e.currentTarget && !isMarqueeSelecting) {
      selectComponent(null);
    }
  };

  // 드래그 영역 선택 시작
  const handleCanvasMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
    // 캔버스 자체를 클릭했을 때만 (컴포넌트 클릭 시 제외)
    if (e.target !== e.currentTarget) return;
    if (!canvasRef.current) return;

    const rect = canvasRef.current.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    // state와 ref 모두 설정
    setIsMarqueeSelecting(true);
    setMarqueeStart({ x, y });
    setMarqueeEnd({ x, y });
    marqueeStartRef.current = { x, y };
    marqueeEndRef.current = { x, y };

    // Ctrl/Cmd 키가 눌리지 않았으면 기존 선택 해제
    if (!e.ctrlKey && !e.metaKey) {
      selectComponent(null);
    }
  };

  // 드래그 영역 선택 중
  useEffect(() => {
    if (!isMarqueeSelecting) return;

    const handleMouseMove = (e: MouseEvent) => {
      if (!canvasRef.current) return;

      const rect = canvasRef.current.getBoundingClientRect();
      const x = Math.max(0, Math.min(e.clientX - rect.left, canvasWidth * MM_TO_PX));
      const y = Math.max(0, Math.min(e.clientY - rect.top, canvasHeight * MM_TO_PX));

      // state와 ref 둘 다 업데이트
      setMarqueeEnd({ x, y });
      marqueeEndRef.current = { x, y };
    };

    const handleMouseUp = () => {
      // ref에서 최신 값 가져오기 (클로저 문제 해결)
      const currentStart = marqueeStartRef.current;
      const currentEnd = marqueeEndRef.current;
      const currentComponents = componentsRef.current;
      const currentSelectMultiple = selectMultipleRef.current;

      // 선택 영역 계산
      const selectionRect = {
        left: Math.min(currentStart.x, currentEnd.x),
        top: Math.min(currentStart.y, currentEnd.y),
        right: Math.max(currentStart.x, currentEnd.x),
        bottom: Math.max(currentStart.y, currentEnd.y),
      };

      // 최소 드래그 거리 체크 (5px 이상이어야 선택으로 인식)
      const dragDistance = Math.sqrt(
        Math.pow(currentEnd.x - currentStart.x, 2) + Math.pow(currentEnd.y - currentStart.y, 2)
      );

      if (dragDistance > 5) {
        // 선택 영역과 교차하는 컴포넌트 찾기
        const intersectingComponents = currentComponents.filter((comp) => {
          const compRect = {
            left: comp.x,
            top: comp.y,
            right: comp.x + comp.width,
            bottom: comp.y + comp.height,
          };

          // 두 사각형이 교차하는지 확인
          return !(
            compRect.right < selectionRect.left ||
            compRect.left > selectionRect.right ||
            compRect.bottom < selectionRect.top ||
            compRect.top > selectionRect.bottom
          );
        });

        // 교차하는 컴포넌트들 한번에 선택
        if (intersectingComponents.length > 0) {
          const ids = intersectingComponents.map((comp) => comp.id);
          currentSelectMultiple(ids);
          // click 이벤트가 선택을 해제하지 않도록 플래그 설정
          justFinishedMarqueeRef.current = true;
        }
      }

      setIsMarqueeSelecting(false);
    };

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

    return () => {
      document.removeEventListener("mousemove", handleMouseMove);
      document.removeEventListener("mouseup", handleMouseUp);
    };
  }, [isMarqueeSelecting, canvasWidth, canvasHeight]);

  // 선택 영역 사각형 계산
  const getMarqueeRect = () => {
    return {
      left: Math.min(marqueeStart.x, marqueeEnd.x),
      top: Math.min(marqueeStart.y, marqueeEnd.y),
      width: Math.abs(marqueeEnd.x - marqueeStart.x),
      height: Math.abs(marqueeEnd.y - marqueeStart.y),
    };
  };

  // 키보드 단축키 (Delete, Ctrl+C, Ctrl+V, 화살표 이동)
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      // 입력 필드에서는 단축키 무시
      const target = e.target as HTMLElement;
      if (target.tagName === "INPUT" || target.tagName === "TEXTAREA") {
        return;
      }

      // 화살표 키: 선택된 컴포넌트 이동
      if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(e.key)) {
        e.preventDefault();

        // 선택된 컴포넌트가 없으면 무시
        if (!selectedComponentId && selectedComponentIds.length === 0) {
          return;
        }

        // 이동 거리 (Shift 키를 누르면 10px, 아니면 1px)
        const moveDistance = e.shiftKey ? 10 : 1;

        // 이동할 컴포넌트 ID 목록
        const idsToMove =
          selectedComponentIds.length > 0 ? selectedComponentIds : ([selectedComponentId].filter(Boolean) as string[]);

        // 각 컴포넌트 이동 (잠긴 컴포넌트는 제외)
        idsToMove.forEach((id) => {
          const component = components.find((c) => c.id === id);
          if (!component || component.locked) return;

          let newX = component.x;
          let newY = component.y;

          switch (e.key) {
            case "ArrowLeft":
              newX = Math.max(0, component.x - moveDistance);
              break;
            case "ArrowRight":
              newX = component.x + moveDistance;
              break;
            case "ArrowUp":
              newY = Math.max(0, component.y - moveDistance);
              break;
            case "ArrowDown":
              newY = component.y + moveDistance;
              break;
          }

          updateComponent(id, { x: newX, y: newY });
        });

        return;
      }

      // Delete 키: 삭제 (잠긴 컴포넌트는 제외)
      if (e.key === "Delete") {
        if (selectedComponentIds.length > 0) {
          selectedComponentIds.forEach((id) => {
            const component = components.find((c) => c.id === id);
            if (component && !component.locked) {
              removeComponent(id);
            }
          });
        } else if (selectedComponentId) {
          const component = components.find((c) => c.id === selectedComponentId);
          if (component && !component.locked) {
            removeComponent(selectedComponentId);
          }
        }
      }

      // Ctrl+Shift+C (또는 Cmd+Shift+C): 스타일 복사 (일반 복사보다 먼저 체크)
      if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === "c") {
        e.preventDefault();
        copyStyles();
        return;
      }

      // Ctrl+Shift+V (또는 Cmd+Shift+V): 스타일 붙여넣기 (일반 붙여넣기보다 먼저 체크)
      if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === "v") {
        e.preventDefault();
        pasteStyles();
        return;
      }

      // Ctrl+Shift+F (또는 Cmd+Shift+F): 텍스트 크기 자동 맞춤
      if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === "f") {
        e.preventDefault();
        fitSelectedToContent();
        return;
      }

      // Ctrl+C (또는 Cmd+C): 복사
      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "c") {
        e.preventDefault();
        copyComponents();
        return;
      }

      // Ctrl+V (또는 Cmd+V): 붙여넣기
      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "v") {
        e.preventDefault();
        pasteComponents();
        return;
      }

      // Ctrl+D (또는 Cmd+D): 복제
      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "d") {
        e.preventDefault();
        duplicateComponents();
        return;
      }

      // Ctrl+Shift+Z 또는 Ctrl+Y (또는 Cmd+Shift+Z / Cmd+Y): Redo (Undo보다 먼저 체크)
      if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === "z") {
        e.preventDefault();
        redo();
        return;
      }
      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "y") {
        e.preventDefault();
        redo();
        return;
      }

      // Ctrl+Z (또는 Cmd+Z): Undo
      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "z") {
        e.preventDefault();
        undo();
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [
    selectedComponentId,
    selectedComponentIds,
    components,
    removeComponent,
    copyComponents,
    pasteComponents,
    duplicateComponents,
    copyStyles,
    pasteStyles,
    fitSelectedToContent,
    undo,
    redo,
  ]);

  // 페이지가 없는 경우
  if (!currentPageId || !currentPage) {
    return (
      <div className="flex flex-1 flex-col items-center justify-center bg-gray-100">
        <div className="text-center">
          <h3 className="text-lg font-semibold text-gray-700">페이지가 없습니다</h3>
          <p className="mt-2 text-sm text-gray-500">좌측에서 페이지를 추가하세요.</p>
        </div>
      </div>
    );
  }

  return (
    <div className="flex flex-1 flex-col overflow-hidden bg-gray-100">
      {/* 캔버스 스크롤 영역 */}
      <div className="flex flex-1 items-center justify-center overflow-auto px-8 pt-[280px] pb-8">
        {/* 눈금자와 캔버스를 감싸는 컨테이너 */}
        <div className="inline-flex flex-col">
          {/* 좌상단 코너 + 가로 눈금자 */}
          {showRuler && (
            <div className="flex">
              {/* 좌상단 코너 (20x20) */}
              <div className="h-5 w-5 bg-gray-200" />
              {/* 가로 눈금자 */}
              <Ruler orientation="horizontal" length={canvasWidth} />
            </div>
          )}

          {/* 세로 눈금자 + 캔버스 */}
          <div className="flex">
            {/* 세로 눈금자 */}
            {showRuler && <Ruler orientation="vertical" length={canvasHeight} />}

            {/* 캔버스 */}
            <div
              ref={(node) => {
                canvasRef.current = node;
                drop(node);
              }}
              className={`relative bg-white shadow-lg ${isOver ? "ring-2 ring-blue-500" : ""}`}
              style={{
                width: `${canvasWidth * MM_TO_PX}px`,
                minHeight: `${canvasHeight * MM_TO_PX}px`,
                backgroundImage: showGrid
                  ? `
                    linear-gradient(to right, #e5e7eb 1px, transparent 1px),
                    linear-gradient(to bottom, #e5e7eb 1px, transparent 1px)
                  `
                  : undefined,
                backgroundSize: showGrid ? `${gridSize}px ${gridSize}px` : undefined,
                cursor: isMarqueeSelecting ? "crosshair" : "default",
              }}
              onClick={handleCanvasClick}
              onMouseDown={handleCanvasMouseDown}
            >
              {/* 페이지 여백 가이드 */}
              {currentPage && (
                <div
                  className="pointer-events-none absolute border-2 border-dashed border-blue-300/50"
                  style={{
                    top: `${currentPage.margins.top * MM_TO_PX}px`,
                    left: `${currentPage.margins.left * MM_TO_PX}px`,
                    right: `${currentPage.margins.right * MM_TO_PX}px`,
                    bottom: `${currentPage.margins.bottom * MM_TO_PX}px`,
                  }}
                />
              )}

              {/* 워터마크 렌더링 (전체 페이지 공유) */}
              {layoutConfig.watermark?.enabled && (
                <WatermarkLayer
                  watermark={layoutConfig.watermark}
                  canvasWidth={canvasWidth * MM_TO_PX}
                  canvasHeight={canvasHeight * MM_TO_PX}
                />
              )}

              {/* 정렬 가이드라인 렌더링 */}
              {alignmentGuides.vertical.map((x, index) => (
                <div
                  key={`v-${index}`}
                  className="pointer-events-none absolute top-0 bottom-0"
                  style={{
                    left: `${x}px`,
                    width: "1px",
                    backgroundColor: "#ef4444",
                    zIndex: 9999,
                  }}
                />
              ))}
              {alignmentGuides.horizontal.map((y, index) => (
                <div
                  key={`h-${index}`}
                  className="pointer-events-none absolute right-0 left-0"
                  style={{
                    top: `${y}px`,
                    height: "1px",
                    backgroundColor: "#ef4444",
                    zIndex: 9999,
                  }}
                />
              ))}

              {/* 컴포넌트 렌더링 */}
              {components.map((component) => (
                <CanvasComponent key={component.id} component={component} />
              ))}

              {/* 드래그 영역 선택 사각형 */}
              {isMarqueeSelecting && (
                <div
                  className="pointer-events-none absolute border-2 border-blue-500 bg-blue-500/10"
                  style={{
                    left: `${getMarqueeRect().left}px`,
                    top: `${getMarqueeRect().top}px`,
                    width: `${getMarqueeRect().width}px`,
                    height: `${getMarqueeRect().height}px`,
                    zIndex: 10000,
                  }}
                />
              )}

              {/* 빈 캔버스 안내 */}
              {components.length === 0 && (
                <div className="absolute inset-0 flex items-center justify-center text-gray-400">
                  <p className="text-sm">왼쪽에서 컴포넌트를 드래그하여 추가하세요</p>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
