"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 { 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,
  } = 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;

      // 새 컴포넌트 생성 (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(200),
        height: snapValueToGrid(item.componentType === "table" ? 200 : 100),
        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,
      };

      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) 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) => removeComponent(id));
        } else if (selectedComponentId) {
          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
          ref={(node) => {
            canvasRef.current = node;
            drop(node);
          }}
          className={`relative mx-auto 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>
  );
}
