"use client";

import { useCallback, useMemo, useRef, useState, useEffect } from "react";
import { useDrop } from "react-dnd";
import GridLayout, { Layout } from "react-grid-layout";
import { cn } from "@/lib/utils";
import {
  PopLayoutDataV2,
  PopLayoutModeKey,
  PopComponentType,
  GridPosition,
  MODE_RESOLUTIONS,
} from "./types/pop-layout";
import { DND_ITEM_TYPES, DragItemSection } from "./panels/PopPanel";
import { GripVertical, Trash2, ZoomIn, ZoomOut, Maximize2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { SectionGridV2 } from "./SectionGridV2";

import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

// ========================================
// 타입 정의
// ========================================
type DeviceType = "mobile" | "tablet";

// 모드별 라벨
const MODE_LABELS: Record<PopLayoutModeKey, string> = {
  tablet_landscape: "태블릿 가로",
  tablet_portrait: "태블릿 세로",
  mobile_landscape: "모바일 가로",
  mobile_portrait: "모바일 세로",
};

// ========================================
// Props
// ========================================
interface PopCanvasProps {
  layout: PopLayoutDataV2;
  activeDevice: DeviceType;
  activeModeKey: PopLayoutModeKey;
  onModeKeyChange: (modeKey: PopLayoutModeKey) => void;
  selectedSectionId: string | null;
  selectedComponentId: string | null;
  onSelectSection: (id: string | null) => void;
  onSelectComponent: (id: string | null) => void;
  onUpdateSectionPosition: (sectionId: string, position: GridPosition, modeKey?: PopLayoutModeKey) => void;
  onUpdateComponentPosition: (componentId: string, position: GridPosition, modeKey?: PopLayoutModeKey) => void;
  onDeleteSection: (id: string) => void;
  onDropSection: (gridPosition: GridPosition) => void;
  onDropComponent: (sectionId: string, type: PopComponentType, gridPosition: GridPosition) => void;
  onDeleteComponent: (sectionId: string, componentId: string) => void;
}

// ========================================
// 메인 컴포넌트
// ========================================
export function PopCanvas({
  layout,
  activeDevice,
  activeModeKey,
  onModeKeyChange,
  selectedSectionId,
  selectedComponentId,
  onSelectSection,
  onSelectComponent,
  onUpdateSectionPosition,
  onUpdateComponentPosition,
  onDeleteSection,
  onDropSection,
  onDropComponent,
  onDeleteComponent,
}: PopCanvasProps) {
  const { settings, sections, components, layouts } = layout;
  const canvasGrid = settings.canvasGrid;

  // 줌 상태 (0.3 ~ 1.0 범위)
  const [canvasScale, setCanvasScale] = useState(0.6);

  // 패닝 상태
  const [isPanning, setIsPanning] = useState(false);
  const [panStart, setPanStart] = useState({ x: 0, y: 0 });
  const [isSpacePressed, setIsSpacePressed] = useState(false); // Space 키 눌림 상태
  const containerRef = useRef<HTMLDivElement>(null);

  // 줌 인 (최대 1.5로 증가)
  const handleZoomIn = () => {
    setCanvasScale((prev) => Math.min(1.5, prev + 0.1));
  };

  // 줌 아웃 (최소 0.3)
  const handleZoomOut = () => {
    setCanvasScale((prev) => Math.max(0.3, prev - 0.1));
  };

  // 맞춤 (1.0)
  const handleZoomFit = () => {
    setCanvasScale(1.0);
  };

  // 패닝 시작 (중앙 마우스 버튼 또는 배경 영역 드래그)
  const handlePanStart = (e: React.MouseEvent) => {
    // 중앙 마우스 버튼(휠 버튼, button === 1) 또는 Space 키 누른 상태
    // 또는 내부 컨테이너(스크롤 영역) 직접 클릭 시
    const isMiddleButton = e.button === 1;
    const isScrollAreaClick = (e.target as HTMLElement).classList.contains("canvas-scroll-area");
    
    if (isMiddleButton || isSpacePressed || isScrollAreaClick) {
      setIsPanning(true);
      setPanStart({ x: e.clientX, y: e.clientY });
      e.preventDefault();
    }
  };

  // 패닝 중
  const handlePanMove = (e: React.MouseEvent) => {
    if (!isPanning || !containerRef.current) return;

    const deltaX = e.clientX - panStart.x;
    const deltaY = e.clientY - panStart.y;

    containerRef.current.scrollLeft -= deltaX;
    containerRef.current.scrollTop -= deltaY;

    setPanStart({ x: e.clientX, y: e.clientY });
  };

  // 패닝 종료
  const handlePanEnd = () => {
    setIsPanning(false);
  };

  // 마우스 휠 줌 (0.3 ~ 1.5 범위)
  const handleWheel = useCallback((e: React.WheelEvent) => {
    e.preventDefault(); // 브라우저 스크롤 방지
    
    const delta = e.deltaY > 0 ? -0.1 : 0.1; // 위로 스크롤: 줌인, 아래로 스크롤: 줌아웃
    setCanvasScale((prev) => Math.max(0.3, Math.min(1.5, prev + delta)));
  }, []);

  // Space 키 감지
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.code === "Space" && !isSpacePressed) {
        setIsSpacePressed(true);
      }
    };

    const handleKeyUp = (e: KeyboardEvent) => {
      if (e.code === "Space") {
        setIsSpacePressed(false);
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    window.addEventListener("keyup", handleKeyUp);

    return () => {
      window.removeEventListener("keydown", handleKeyDown);
      window.removeEventListener("keyup", handleKeyUp);
    };
  }, [isSpacePressed]);

  // 초기 로드 시 캔버스를 중앙으로 스크롤
  useEffect(() => {
    if (containerRef.current) {
      const container = containerRef.current;
      // 약간의 딜레이 후 중앙으로 스크롤 (DOM이 완전히 렌더링된 후)
      const timer = setTimeout(() => {
        const scrollX = (container.scrollWidth - container.clientWidth) / 2;
        const scrollY = (container.scrollHeight - container.clientHeight) / 2;
        container.scrollTo(scrollX, scrollY);
      }, 100);
      return () => clearTimeout(timer);
    }
  }, [activeDevice]); // 디바이스 변경 시 재중앙화

  // 현재 디바이스의 가로/세로 모드 키
  const landscapeModeKey: PopLayoutModeKey = activeDevice === "tablet" 
    ? "tablet_landscape" 
    : "mobile_landscape";
  const portraitModeKey: PopLayoutModeKey = activeDevice === "tablet" 
    ? "tablet_portrait" 
    : "mobile_portrait";

  // 단일 캔버스 프레임 렌더링
  const renderDeviceFrame = (modeKey: PopLayoutModeKey) => {
    const resolution = MODE_RESOLUTIONS[modeKey];
    const isActive = modeKey === activeModeKey;
    const modeLayout = layouts[modeKey];

    // 이 모드의 섹션 위치 목록
    const sectionPositions = modeLayout.sectionPositions;
    const sectionIds = Object.keys(sectionPositions);

    // GridLayout용 레이아웃 아이템 생성
    const gridLayoutItems: Layout[] = sectionIds.map((sectionId) => {
      const pos = sectionPositions[sectionId];
      return {
        i: sectionId,
        x: pos.col - 1,
        y: pos.row - 1,
        w: pos.colSpan,
        h: pos.rowSpan,
        minW: 2,
        minH: 1,
      };
    });

    const cols = canvasGrid.columns;
    const rowHeight = canvasGrid.rowHeight;
    const margin: [number, number] = [canvasGrid.gap, canvasGrid.gap];

    const sizeLabel = `${resolution.width}x${resolution.height}`;
    const modeLabel = `${MODE_LABELS[modeKey]} (${sizeLabel})`;

    // 드래그/리사이즈 완료 핸들러
    const handleDragResizeStop = (
      layoutItems: Layout[],
      oldItem: Layout,
      newItem: Layout
    ) => {
      const newPos: GridPosition = {
        col: newItem.x + 1,
        row: newItem.y + 1,
        colSpan: newItem.w,
        rowSpan: newItem.h,
      };
      onUpdateSectionPosition(newItem.i, newPos, modeKey);
    };

    return (
      <div
        key={modeKey}
        className={cn(
          "relative shrink-0 cursor-pointer rounded-lg border-4 bg-white shadow-xl transition-all",
          isActive 
            ? "border-primary ring-2 ring-primary/30" 
            : "border-gray-300 hover:border-gray-400"
        )}
        style={{
          width: resolution.width * canvasScale,
          height: resolution.height * canvasScale,
        }}
        onClick={() => {
          if (!isActive) {
            onModeKeyChange(modeKey);
          }
        }}
      >
        {/* 모드 라벨 */}
        <div
          className={cn(
            "absolute -top-6 left-1/2 -translate-x-1/2 whitespace-nowrap text-xs font-medium",
            isActive ? "text-primary" : "text-muted-foreground"
          )}
        >
          {modeLabel}
        </div>

        {/* 활성 표시 배지 */}
        {isActive && (
          <div className="absolute right-2 top-2 rounded-full bg-primary px-2 py-0.5 text-[10px] font-bold text-white shadow-lg">
            편집 중
          </div>
        )}

        {/* 드롭 영역 */}
        <CanvasDropZone
          modeKey={modeKey}
          isActive={isActive}
          resolution={resolution}
          scale={canvasScale}
          cols={cols}
          rowHeight={rowHeight}
          margin={margin}
          sections={sections}
          components={components}
          sectionPositions={sectionPositions}
          componentPositions={modeLayout.componentPositions}
          gridLayoutItems={gridLayoutItems}
          selectedSectionId={selectedSectionId}
          selectedComponentId={selectedComponentId}
          onSelectSection={onSelectSection}
          onSelectComponent={onSelectComponent}
          onDragResizeStop={handleDragResizeStop}
          onDropSection={onDropSection}
          onDropComponent={onDropComponent}
          onUpdateComponentPosition={(compId, pos) => onUpdateComponentPosition(compId, pos, modeKey)}
          onDeleteSection={onDeleteSection}
          onDeleteComponent={onDeleteComponent}
        />
      </div>
    );
  };

  return (
    <div className="relative flex h-full flex-col bg-gray-50">
      {/* 줌 컨트롤 바 */}
      <div className="flex shrink-0 items-center justify-end gap-2 border-b bg-white px-4 py-2">
        <span className="text-xs text-muted-foreground">
          줌: {Math.round(canvasScale * 100)}%
        </span>
        <Button
          variant="outline"
          size="icon"
          className="h-7 w-7"
          onClick={handleZoomOut}
          title="줌 아웃"
        >
          <ZoomOut className="h-4 w-4" />
        </Button>
        <Button
          variant="outline"
          size="icon"
          className="h-7 w-7"
          onClick={handleZoomIn}
          title="줌 인"
        >
          <ZoomIn className="h-4 w-4" />
        </Button>
        <Button
          variant="outline"
          size="icon"
          className="h-7 w-7"
          onClick={handleZoomFit}
          title="맞춤 (100%)"
        >
          <Maximize2 className="h-4 w-4" />
        </Button>
      </div>

      {/* 캔버스 영역 (패닝 가능) */}
      <div
        ref={containerRef}
        className={cn(
          "relative flex-1 overflow-auto",
          isPanning && "cursor-grabbing",
          isSpacePressed && "cursor-grab"
        )}
        onMouseDown={handlePanStart}
        onMouseMove={handlePanMove}
        onMouseUp={handlePanEnd}
        onMouseLeave={handlePanEnd}
        onWheel={handleWheel}
      >
        {/* 스크롤 가능한 큰 영역 - 빈 공간 클릭 시 패닝 가능 */}
        <div 
          className="canvas-scroll-area flex items-center justify-center gap-16"
          style={{
            // 캔버스 주변에 충분한 여백 확보 (상하좌우 500px씩)
            padding: "500px",
            minWidth: "fit-content",
            minHeight: "fit-content",
          }}
        >
          {/* 가로 모드 캔버스 */}
          {renderDeviceFrame(landscapeModeKey)}
          
          {/* 세로 모드 캔버스 */}
          {renderDeviceFrame(portraitModeKey)}
        </div>
      </div>
    </div>
  );
}

// ========================================
// 캔버스 드롭 영역 컴포넌트
// ========================================
interface CanvasDropZoneProps {
  modeKey: PopLayoutModeKey;
  isActive: boolean;
  resolution: { width: number; height: number };
  scale: number;
  cols: number;
  rowHeight: number;
  margin: [number, number];
  sections: PopLayoutDataV2["sections"];
  components: PopLayoutDataV2["components"];
  sectionPositions: Record<string, GridPosition>;
  componentPositions: Record<string, GridPosition>;
  gridLayoutItems: Layout[];
  selectedSectionId: string | null;
  selectedComponentId: string | null;
  onSelectSection: (id: string | null) => void;
  onSelectComponent: (id: string | null) => void;
  onDragResizeStop: (layout: Layout[], oldItem: Layout, newItem: Layout) => void;
  onDropSection: (gridPosition: GridPosition) => void;
  onDropComponent: (sectionId: string, type: PopComponentType, gridPosition: GridPosition) => void;
  onUpdateComponentPosition: (componentId: string, position: GridPosition) => void;
  onDeleteSection: (id: string) => void;
  onDeleteComponent: (sectionId: string, componentId: string) => void;
}

function CanvasDropZone({
  modeKey,
  isActive,
  resolution,
  scale,
  cols,
  rowHeight,
  margin,
  sections,
  components,
  sectionPositions,
  componentPositions,
  gridLayoutItems,
  selectedSectionId,
  selectedComponentId,
  onSelectSection,
  onSelectComponent,
  onDragResizeStop,
  onDropSection,
  onDropComponent,
  onUpdateComponentPosition,
  onDeleteSection,
  onDeleteComponent,
}: CanvasDropZoneProps) {
  const dropRef = useRef<HTMLDivElement>(null);

  // 스케일 적용된 크기
  const scaledWidth = resolution.width * scale;
  const scaledHeight = resolution.height * scale;

  // 섹션 드롭 핸들러
  const [{ isOver, canDrop }, drop] = useDrop(
    () => ({
      accept: DND_ITEM_TYPES.SECTION,
      drop: (item: DragItemSection, monitor) => {
        if (!isActive) return;

        const clientOffset = monitor.getClientOffset();
        if (!clientOffset || !dropRef.current) return;

        const dropRect = dropRef.current.getBoundingClientRect();
        // 스케일 보정
        const x = (clientOffset.x - dropRect.left) / scale;
        const y = (clientOffset.y - dropRect.top) / scale;

        // 그리드 위치 계산
        const colWidth = (resolution.width - 16) / cols;
        const col = Math.max(1, Math.min(cols, Math.floor(x / colWidth) + 1));
        const row = Math.max(1, Math.floor(y / (rowHeight * scale)) + 1);

        onDropSection({
          col,
          row,
          colSpan: 3,
          rowSpan: 4,
        });
      },
      canDrop: () => isActive,
      collect: (monitor) => ({
        isOver: monitor.isOver(),
        canDrop: monitor.canDrop(),
      }),
    }),
    [isActive, resolution, scale, cols, rowHeight, onDropSection]
  );

  drop(dropRef);

  const sectionIds = Object.keys(sectionPositions);

  return (
    <div
      ref={dropRef}
      className={cn(
        "h-full w-full overflow-hidden rounded-md bg-gray-100 p-1 transition-colors",
        isOver && canDrop && "bg-primary/10 ring-2 ring-primary ring-inset"
      )}
      style={{
        // 내부 컨텐츠를 스케일 조정
        transform: `scale(${scale})`,
        transformOrigin: "top left",
        width: resolution.width,
        height: resolution.height,
      }}
      onClick={(e) => {
        if (e.target === e.currentTarget) {
          onSelectSection(null);
          onSelectComponent(null);
        }
      }}
    >
      {sectionIds.length > 0 ? (
        <GridLayout
          className="layout"
          layout={gridLayoutItems}
          cols={cols}
          rowHeight={rowHeight}
          width={resolution.width - 8}
          margin={margin}
          containerPadding={[0, 0]}
          onDragStop={onDragResizeStop}
          onResizeStop={onDragResizeStop}
          isDraggable={isActive}
          isResizable={isActive}
          compactType={null}
          preventCollision={false}
          useCSSTransforms={true}
          draggableHandle=".section-drag-handle"
        >
          {sectionIds.map((sectionId) => {
            const sectionDef = sections[sectionId];
            if (!sectionDef) return null;

            return (
              <div
                key={sectionId}
                className={cn(
                  "group relative flex flex-col overflow-hidden rounded-lg border-2 bg-white transition-all",
                  selectedSectionId === sectionId
                    ? "border-primary ring-2 ring-primary/30"
                    : "border-gray-200 hover:border-gray-400"
                )}
                onClick={(e) => {
                  e.stopPropagation();
                  onSelectSection(sectionId);
                }}
              >
                {/* 섹션 헤더 */}
                <div
                  className={cn(
                    "section-drag-handle flex h-7 shrink-0 cursor-move items-center justify-between border-b px-2",
                    selectedSectionId === sectionId ? "bg-primary/10" : "bg-gray-50"
                  )}
                >
                  <div className="flex items-center gap-1">
                    <GripVertical className="h-3 w-3 text-gray-400" />
                    <span className="text-xs font-medium text-gray-600">
                      {sectionDef.label || "섹션"}
                    </span>
                  </div>
                  {selectedSectionId === sectionId && isActive && (
                    <Button
                      variant="ghost"
                      size="icon"
                      className="h-5 w-5 text-destructive hover:bg-destructive/10"
                      onClick={(e) => {
                        e.stopPropagation();
                        onDeleteSection(sectionId);
                      }}
                    >
                      <Trash2 className="h-3 w-3" />
                    </Button>
                  )}
                </div>

                {/* 섹션 내부 - 컴포넌트들 */}
                <div className="relative flex-1">
                  <SectionGridV2
                    sectionId={sectionId}
                    sectionDef={sectionDef}
                    components={components}
                    componentPositions={componentPositions}
                    isActive={isActive}
                    selectedComponentId={selectedComponentId}
                    onSelectComponent={onSelectComponent}
                    onDropComponent={onDropComponent}
                    onUpdateComponentPosition={onUpdateComponentPosition}
                    onDeleteComponent={onDeleteComponent}
                  />
                </div>
              </div>
            );
          })}
        </GridLayout>
      ) : (
        <div
          className={cn(
            "flex h-full items-center justify-center rounded-lg border-2 border-dashed text-sm",
            isOver && canDrop
              ? "border-primary bg-primary/5 text-primary"
              : "border-gray-300 text-gray-400"
          )}
        >
          {isOver && canDrop
            ? "여기에 섹션을 놓으세요"
            : isActive
            ? "왼쪽 패널에서 섹션을 드래그하세요"
            : "클릭하여 편집 모드로 전환"}
        </div>
      )}
    </div>
  );
}
