"use client";

import { useCallback, useRef, useState, useEffect, useMemo } from "react";
import { useDrop } from "react-dnd";
import { cn } from "@/lib/utils";
import {
  PopLayoutDataV5,
  PopComponentDefinitionV5,
  PopComponentType,
  PopGridPosition,
  GridMode,
  GRID_BREAKPOINTS,
  DEFAULT_COMPONENT_GRID_SIZE,
} from "./types/pop-layout";
import { ZoomIn, ZoomOut, Maximize2, Smartphone, Tablet } from "lucide-react";
import { Button } from "@/components/ui/button";
import PopRenderer from "./renderers/PopRenderer";
import { mouseToGridPosition, findNextEmptyPosition } from "./utils/gridUtils";

// DnD 타입 상수 (인라인)
const DND_ITEM_TYPES = {
  COMPONENT: "component",
} as const;

interface DragItemComponent {
  type: typeof DND_ITEM_TYPES.COMPONENT;
  componentType: PopComponentType;
}

// ========================================
// 프리셋 해상도 (4개 모드)
// ========================================
const VIEWPORT_PRESETS = [
  { id: "mobile_portrait", label: "모바일 세로", shortLabel: "모바일↕ (4칸)", width: 375, height: 667, icon: Smartphone },
  { id: "mobile_landscape", label: "모바일 가로", shortLabel: "모바일↔ (6칸)", width: 667, height: 375, icon: Smartphone },
  { id: "tablet_portrait", label: "태블릿 세로", shortLabel: "태블릿↕ (8칸)", width: 768, height: 1024, icon: Tablet },
  { id: "tablet_landscape", label: "태블릿 가로", shortLabel: "태블릿↔ (12칸)", width: 1024, height: 768, icon: Tablet },
] as const;

type ViewportPreset = GridMode;

// 기본 프리셋 (태블릿 가로)
const DEFAULT_PRESET: ViewportPreset = "tablet_landscape";

// ========================================
// Props
// ========================================
interface PopCanvasProps {
  layout: PopLayoutDataV5;
  selectedComponentId: string | null;
  currentMode: GridMode;
  onModeChange: (mode: GridMode) => void;
  onSelectComponent: (id: string | null) => void;
  onDropComponent: (type: PopComponentType, position: PopGridPosition) => void;
  onUpdateComponent: (componentId: string, updates: Partial<PopComponentDefinitionV5>) => void;
  onDeleteComponent: (componentId: string) => void;
  onMoveComponent?: (componentId: string, newPosition: PopGridPosition) => void;
  onResizeComponent?: (componentId: string, newPosition: PopGridPosition) => void;
}

// ========================================
// PopCanvas: 그리드 캔버스
// ========================================

export default function PopCanvas({
  layout,
  selectedComponentId,
  currentMode,
  onModeChange,
  onSelectComponent,
  onDropComponent,
  onUpdateComponent,
  onDeleteComponent,
  onMoveComponent,
  onResizeComponent,
}: PopCanvasProps) {
  // 줌 상태
  const [canvasScale, setCanvasScale] = useState(0.8);
  
  // 커스텀 뷰포트 크기
  const [customWidth, setCustomWidth] = useState(1024);
  const [customHeight, setCustomHeight] = useState(768);
  
  // 그리드 가이드 표시 여부
  const [showGridGuide, setShowGridGuide] = useState(true);
  
  // 패닝 상태
  const [isPanning, setIsPanning] = useState(false);
  const [panStart, setPanStart] = useState({ x: 0, y: 0 });
  const [isSpacePressed, setIsSpacePressed] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);
  const canvasRef = useRef<HTMLDivElement>(null);
  
  // 드래그 상태
  const [isDraggingComponent, setIsDraggingComponent] = useState(false);
  const [draggedComponentId, setDraggedComponentId] = useState<string | null>(null);
  const [dragStartPos, setDragStartPos] = useState<{ x: number; y: number } | null>(null);
  const [dragPreviewPos, setDragPreviewPos] = useState<PopGridPosition | null>(null);

  // 현재 뷰포트 해상도
  const currentPreset = VIEWPORT_PRESETS.find((p) => p.id === currentMode)!;
  const breakpoint = GRID_BREAKPOINTS[currentMode];
  
  // 그리드 라벨 계산
  const gridLabels = useMemo(() => {
    const columnLabels = Array.from({ length: breakpoint.columns }, (_, i) => i + 1);
    const rowLabels = Array.from({ length: 20 }, (_, i) => i + 1);
    return { columnLabels, rowLabels };
  }, [breakpoint.columns]);

  // 줌 컨트롤
  const handleZoomIn = () => setCanvasScale((prev) => Math.min(1.5, prev + 0.1));
  const handleZoomOut = () => setCanvasScale((prev) => Math.max(0.3, prev - 0.1));
  const handleZoomFit = () => setCanvasScale(1.0);

  // 모드 변경
  const handleViewportChange = (mode: GridMode) => {
    onModeChange(mode);
    const presetData = VIEWPORT_PRESETS.find((p) => p.id === mode)!;
    setCustomWidth(presetData.width);
    setCustomHeight(presetData.height);
  };

  // 패닝
  const handlePanStart = (e: React.MouseEvent) => {
    const isMiddleButton = e.button === 1;
    if (isMiddleButton || isSpacePressed) {
      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);

  // Ctrl + 휠로 줌 조정
  const handleWheel = (e: React.WheelEvent) => {
    if (e.ctrlKey || e.metaKey) {
      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]);

  // 컴포넌트 드롭 (팔레트에서)
  const [{ isOver, canDrop }, drop] = useDrop(
    () => ({
      accept: DND_ITEM_TYPES.COMPONENT,
      drop: (item: DragItemComponent, monitor) => {
        if (!canvasRef.current) return;
        
        const offset = monitor.getClientOffset();
        if (!offset) return;
        
        const canvasRect = canvasRef.current.getBoundingClientRect();
        
        // 마우스 위치 → 그리드 좌표 변환
        const gridPos = mouseToGridPosition(
          offset.x,
          offset.y,
          canvasRect,
          breakpoint.columns,
          breakpoint.rowHeight,
          breakpoint.gap,
          breakpoint.padding
        );
        
        // 컴포넌트 기본 크기
        const defaultSize = DEFAULT_COMPONENT_GRID_SIZE[item.componentType];
        
        // 다음 빈 위치 찾기
        const existingPositions = Object.values(layout.components).map(c => c.position);
        const position = findNextEmptyPosition(
          existingPositions,
          defaultSize.colSpan,
          defaultSize.rowSpan,
          breakpoint.columns
        );
        
        // 컴포넌트 추가
        onDropComponent(item.componentType, position);
      },
      collect: (monitor) => ({
        isOver: monitor.isOver(),
        canDrop: monitor.canDrop(),
      }),
    }),
    [onDropComponent, breakpoint, layout.components]
  );

  drop(canvasRef);

  // 빈 상태 체크
  const isEmpty = Object.keys(layout.components).length === 0;

  return (
    <div className="flex h-full flex-col bg-gray-50">
      {/* 상단 컨트롤 */}
      <div className="flex items-center gap-2 border-b bg-white px-4 py-2">
        {/* 모드 프리셋 버튼 */}
        <div className="flex gap-1">
          {VIEWPORT_PRESETS.map((preset) => {
            const Icon = preset.icon;
            const isActive = currentMode === preset.id;
            const isDefault = preset.id === DEFAULT_PRESET;
            
            return (
              <Button
                key={preset.id}
                variant={isActive ? "default" : "outline"}
                size="sm"
                onClick={() => handleViewportChange(preset.id as GridMode)}
                className={cn(
                  "h-8 gap-1 text-xs",
                  isActive && "shadow-sm"
                )}
              >
                <Icon className="h-3 w-3" />
                {preset.shortLabel}
                {isDefault && " (기본)"}
              </Button>
            );
          })}
        </div>

        <div className="h-4 w-px bg-gray-300" />

        {/* 해상도 표시 */}
        <div className="text-xs text-muted-foreground">
          {customWidth} × {customHeight}
        </div>

        <div className="flex-1" />

        {/* 줌 컨트롤 */}
        <div className="flex items-center gap-1">
          <span className="text-xs text-muted-foreground">
            {Math.round(canvasScale * 100)}%
          </span>
          <Button
            variant="ghost"
            size="icon"
            onClick={handleZoomOut}
            disabled={canvasScale <= 0.3}
            className="h-7 w-7"
          >
            <ZoomOut className="h-3 w-3" />
          </Button>
          <Button
            variant="ghost"
            size="icon"
            onClick={handleZoomFit}
            className="h-7 w-7"
          >
            <Maximize2 className="h-3 w-3" />
          </Button>
          <Button
            variant="ghost"
            size="icon"
            onClick={handleZoomIn}
            disabled={canvasScale >= 1.5}
            className="h-7 w-7"
          >
            <ZoomIn className="h-3 w-3" />
          </Button>
        </div>
        
        <div className="h-4 w-px bg-gray-300" />
        
        {/* 그리드 가이드 토글 */}
        <Button
          variant={showGridGuide ? "default" : "outline"}
          size="sm"
          onClick={() => setShowGridGuide(!showGridGuide)}
          className="h-8 text-xs"
        >
          그리드 {showGridGuide ? "ON" : "OFF"}
        </Button>
      </div>

      {/* 캔버스 영역 */}
      <div
        ref={containerRef}
        className={cn(
          "canvas-scroll-area relative flex-1 overflow-auto bg-gray-100",
          isSpacePressed && "cursor-grab",
          isPanning && "cursor-grabbing"
        )}
        onMouseDown={handlePanStart}
        onMouseMove={handlePanMove}
        onMouseUp={handlePanEnd}
        onMouseLeave={handlePanEnd}
        onWheel={handleWheel}
      >
        <div
          className="relative mx-auto my-8 origin-top"
          style={{
            width: `${customWidth + 32}px`, // 라벨 공간 추가
            minHeight: `${customHeight + 32}px`,
            transform: `scale(${canvasScale})`,
          }}
        >
          {/* 그리드 라벨 영역 */}
          {showGridGuide && (
            <>
              {/* 열 라벨 (상단) */}
              <div 
                className="flex absolute top-0 left-8"
                style={{
                  gap: `${breakpoint.gap}px`,
                  paddingLeft: `${breakpoint.padding}px`,
                }}
              >
                {gridLabels.columnLabels.map((num) => (
                  <div
                    key={`col-${num}`}
                    className="flex items-center justify-center text-xs font-semibold text-blue-500"
                    style={{
                      width: `calc((${customWidth}px - ${breakpoint.padding * 2}px - ${breakpoint.gap * (breakpoint.columns - 1)}px) / ${breakpoint.columns})`,
                      height: "24px",
                    }}
                  >
                    {num}
                  </div>
                ))}
              </div>
              
              {/* 행 라벨 (좌측) */}
              <div 
                className="flex flex-col absolute top-8 left-0"
                style={{
                  gap: `${breakpoint.gap}px`,
                  paddingTop: `${breakpoint.padding}px`,
                }}
              >
                {gridLabels.rowLabels.map((num) => (
                  <div
                    key={`row-${num}`}
                    className="flex items-center justify-center text-xs font-semibold text-blue-500"
                    style={{
                      width: "24px",
                      height: `${breakpoint.rowHeight}px`,
                    }}
                  >
                    {num}
                  </div>
                ))}
              </div>
            </>
          )}
          
          {/* 디바이스 스크린 */}
          <div
            ref={canvasRef}
            className={cn(
              "relative rounded-lg border-2 bg-white shadow-xl overflow-hidden",
              canDrop && isOver && "ring-4 ring-primary/20"
            )}
            style={{
              width: `${customWidth}px`,
              minHeight: `${customHeight}px`,
              marginLeft: "32px",
              marginTop: "32px",
            }}
          >
            {isEmpty ? (
              // 빈 상태
              <div className="flex h-full items-center justify-center p-8">
                <div className="text-center">
                  <div className="mb-2 text-sm font-medium text-gray-500">
                    컴포넌트를 드래그하여 배치하세요
                  </div>
                  <div className="text-xs text-gray-400">
                    {breakpoint.label} - {breakpoint.columns}칸 그리드
                  </div>
                </div>
              </div>
            ) : (
              // 그리드 렌더러
              <PopRenderer
                layout={layout}
                viewportWidth={customWidth}
                currentMode={currentMode}
                isDesignMode={true}
                showGridGuide={showGridGuide}
                selectedComponentId={selectedComponentId}
                onComponentClick={onSelectComponent}
                onBackgroundClick={() => onSelectComponent(null)}
              />
            )}
          </div>
        </div>
      </div>

      {/* 하단 정보 */}
      <div className="flex items-center justify-between border-t bg-white px-4 py-2">
        <div className="text-xs text-muted-foreground">
          {breakpoint.label} - {breakpoint.columns}칸 그리드 (행 높이: {breakpoint.rowHeight}px)
        </div>
        <div className="text-xs text-muted-foreground">
          Space + 드래그: 패닝 | Ctrl + 휠: 줌
        </div>
      </div>
    </div>
  );
}
