"use client";

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

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

  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 = 2;
      } else if (item.componentType === "signature") {
        width = 120;
        height = 70;
      } else if (item.componentType === "stamp") {
        width = 70;
        height = 70;
      }

      // 새 컴포넌트 생성 (Grid Snap 적용)
      const newComponent: ComponentConfig = {
        id: `comp_${uuidv4()}`,
        type: item.componentType,
        x: snapValueToGrid(Math.max(0, x - 100)),
        y: snapValueToGrid(Math.max(0, y - 25)),
        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,
          showUnderline: true,
          borderWidth: 1,
          borderColor: "#cccccc",
        }),
        // 도장란 전용
        ...(item.componentType === "stamp" && {
          imageUrl: "",
          objectFit: "contain" as const,
          showLabel: true,
          labelText: "(인)",
          labelPosition: "top" as const,
          personName: "",
          borderWidth: 1,
          borderColor: "#cccccc",
        }),
        // 테이블 전용
        ...(item.componentType === "table" && {
          queryId: undefined,
          tableColumns: [],
          headerBackgroundColor: "#f3f4f6",
          headerTextColor: "#111827",
          showBorder: true,
          rowHeight: 32,
        }),
      };

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

  const handleCanvasClick = (e: React.MouseEvent<HTMLDivElement>) => {
    if (e.target === e.currentTarget) {
      selectComponent(null);
    }
  };

  // 키보드 단축키 (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+C (또는 Cmd+C): 복사
      if ((e.ctrlKey || e.metaKey) && e.key === "c") {
        e.preventDefault();
        copyComponents();
      }

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

      // 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,
    undo,
    redo,
  ]);

  return (
    <div className="flex flex-1 flex-col overflow-hidden bg-gray-100">
      {/* 작업 영역 제목 */}
      <div className="border-b bg-white px-4 py-2 text-center text-sm font-medium text-gray-700">작업 영역</div>

      {/* 캔버스 스크롤 영역 */}
      <div className="flex-1 overflow-auto p-8">
        {/* 눈금자와 캔버스를 감싸는 컨테이너 */}
        <div className="mx-auto 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`,
                minHeight: `${canvasHeight}mm`,
                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,
              }}
              onClick={handleCanvasClick}
            >
              {/* 정렬 가이드라인 렌더링 */}
              {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} />
              ))}

              {/* 빈 캔버스 안내 */}
              {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>
  );
}
