"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 {
  PopSectionData,
  PopComponentData,
  PopComponentType,
  GridPosition,
} from "./types/pop-layout";
import { DND_ITEM_TYPES, DragItemComponent } from "./panels/PopPanel";
import { Trash2, Move } from "lucide-react";
import { Button } from "@/components/ui/button";

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

interface SectionGridProps {
  section: PopSectionData;
  isActive: boolean;
  selectedComponentId: string | null;
  onSelectComponent: (id: string | null) => void;
  onDropComponent: (sectionId: string, type: PopComponentType, gridPosition: GridPosition) => void;
  onUpdateComponent: (sectionId: string, componentId: string, updates: Partial<PopComponentData>) => void;
  onDeleteComponent: (sectionId: string, componentId: string) => void;
}

export function SectionGrid({
  section,
  isActive,
  selectedComponentId,
  onSelectComponent,
  onDropComponent,
  onUpdateComponent,
  onDeleteComponent,
}: SectionGridProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const { components } = section;
  
  // 컨테이너 크기 측정
  const [containerSize, setContainerSize] = useState({ width: 300, height: 200 });
  
  useEffect(() => {
    const updateSize = () => {
      if (containerRef.current) {
        setContainerSize({
          width: containerRef.current.offsetWidth,
          height: containerRef.current.offsetHeight,
        });
      }
    };
    
    updateSize();
    
    const resizeObserver = new ResizeObserver(updateSize);
    if (containerRef.current) {
      resizeObserver.observe(containerRef.current);
    }
    
    return () => resizeObserver.disconnect();
  }, []);

  // 셀 크기 계산 - 고정 셀 크기 기반으로 자동 계산
  const padding = 8; // p-2 = 8px
  const gap = 4; // 고정 간격
  const availableWidth = containerSize.width - padding * 2;
  const availableHeight = containerSize.height - padding * 2;
  
  // 고정 셀 크기 (40px) 기반으로 열/행 수 자동 계산
  const CELL_SIZE = 40;
  const cols = Math.max(1, Math.floor((availableWidth + gap) / (CELL_SIZE + gap)));
  const rows = Math.max(1, Math.floor((availableHeight + gap) / (CELL_SIZE + gap)));
  const cellHeight = CELL_SIZE;

  // GridLayout용 레이아웃 변환 (자동 계산된 cols/rows 사용)
  const gridLayoutItems: Layout[] = useMemo(() => {
    return components.map((comp) => {
      // 컴포넌트 위치가 그리드 범위를 벗어나지 않도록 조정
      const x = Math.min(Math.max(0, comp.grid.col - 1), Math.max(0, cols - 1));
      const y = Math.min(Math.max(0, comp.grid.row - 1), Math.max(0, rows - 1));
      // colSpan/rowSpan도 범위 제한
      const w = Math.min(Math.max(1, comp.grid.colSpan), Math.max(1, cols - x));
      const h = Math.min(Math.max(1, comp.grid.rowSpan), Math.max(1, rows - y));
      
      return {
        i: comp.id,
        x,
        y,
        w,
        h,
        minW: 1,
        minH: 1,
      };
    });
  }, [components, cols, rows]);

  // 드래그/리사이즈 완료 핸들러 (onDragStop, onResizeStop 사용)
  const handleDragStop = useCallback(
    (layout: Layout[], oldItem: Layout, newItem: Layout) => {
      const comp = components.find((c) => c.id === newItem.i);
      if (!comp) return;

      const newGrid: GridPosition = {
        col: newItem.x + 1,
        row: newItem.y + 1,
        colSpan: newItem.w,
        rowSpan: newItem.h,
      };

      if (
        comp.grid.col !== newGrid.col ||
        comp.grid.row !== newGrid.row
      ) {
        onUpdateComponent(section.id, comp.id, { grid: newGrid });
      }
    },
    [components, section.id, onUpdateComponent]
  );

  const handleResizeStop = useCallback(
    (layout: Layout[], oldItem: Layout, newItem: Layout) => {
      const comp = components.find((c) => c.id === newItem.i);
      if (!comp) return;

      const newGrid: GridPosition = {
        col: newItem.x + 1,
        row: newItem.y + 1,
        colSpan: newItem.w,
        rowSpan: newItem.h,
      };

      if (
        comp.grid.colSpan !== newGrid.colSpan ||
        comp.grid.rowSpan !== newGrid.rowSpan
      ) {
        onUpdateComponent(section.id, comp.id, { grid: newGrid });
      }
    },
    [components, section.id, onUpdateComponent]
  );

  // 빈 셀 찾기 (드롭 위치용) - 자동 계산된 cols/rows 사용
  const findEmptyCell = useCallback((): GridPosition => {
    const occupied = new Set<string>();
    
    components.forEach((comp) => {
      for (let c = comp.grid.col; c < comp.grid.col + comp.grid.colSpan; c++) {
        for (let r = comp.grid.row; r < comp.grid.row + comp.grid.rowSpan; r++) {
          occupied.add(`${c}-${r}`);
        }
      }
    });

    // 빈 셀 찾기
    for (let r = 1; r <= rows; r++) {
      for (let c = 1; c <= cols; c++) {
        if (!occupied.has(`${c}-${r}`)) {
          return { col: c, row: r, colSpan: 1, rowSpan: 1 };
        }
      }
    }

    // 빈 셀 없으면 첫 번째 위치에
    return { col: 1, row: 1, colSpan: 1, rowSpan: 1 };
  }, [components, cols, rows]);

  // 컴포넌트 드롭 핸들러
  const [{ isOver, canDrop }, drop] = useDrop(() => ({
    accept: DND_ITEM_TYPES.COMPONENT,
    drop: (item: DragItemComponent) => {
      if (!isActive) return;
      const emptyCell = findEmptyCell();
      onDropComponent(section.id, item.componentType, emptyCell);
      return { dropped: true };
    },
    canDrop: () => isActive,
    collect: (monitor) => ({
      isOver: monitor.isOver(),
      canDrop: monitor.canDrop(),
    }),
  }), [isActive, section.id, findEmptyCell, onDropComponent]);


  return (
    <div
      ref={(node) => {
        containerRef.current = node;
        drop(node);
      }}
      className={cn(
        "relative h-full w-full p-2 transition-colors",
        isOver && canDrop && "bg-blue-50"
      )}
      onClick={(e) => {
        e.stopPropagation();
        onSelectComponent(null);
      }}
      onMouseDown={(e) => {
        e.stopPropagation();
      }}
    >

      {/* 빈 상태 안내 텍스트 */}
      {components.length === 0 && (
        <div className="pointer-events-none absolute inset-0 flex items-center justify-center z-10">
          <span className={cn(
            "rounded bg-white/80 px-2 py-1 text-xs",
            isOver && canDrop ? "text-primary font-medium" : "text-gray-400"
          )}>
            {isOver && canDrop ? "여기에 놓으세요" : "컴포넌트를 드래그하세요"}
          </span>
        </div>
      )}

      {/* 컴포넌트 GridLayout */}
      {components.length > 0 && availableWidth > 0 && cols > 0 && (
        <GridLayout
          className="layout relative z-10"
          layout={gridLayoutItems}
          cols={cols}
          rowHeight={cellHeight}
          width={availableWidth}
          margin={[gap, gap]}
          containerPadding={[0, 0]}
          onDragStop={handleDragStop}
          onResizeStop={handleResizeStop}
          isDraggable={isActive}
          isResizable={isActive}
          compactType={null}
          preventCollision={false}
          useCSSTransforms={true}
          draggableHandle=".component-drag-handle"
          resizeHandles={["se", "e", "s"]}
        >
          {components.map((comp) => (
            <div
              key={comp.id}
              className={cn(
                "group relative flex flex-col rounded border bg-white text-xs transition-all overflow-hidden",
                selectedComponentId === comp.id
                  ? "border-primary ring-2 ring-primary/30"
                  : "border-gray-200 hover:border-gray-400"
              )}
              onClick={(e) => {
                e.stopPropagation();
                onSelectComponent(comp.id);
              }}
              onMouseDown={(e) => e.stopPropagation()}
            >
              {/* 드래그 핸들 바 */}
              <div className="component-drag-handle flex h-5 cursor-move items-center justify-center border-b bg-gray-50 opacity-60 hover:opacity-100 transition-opacity">
                <Move className="h-3 w-3 text-gray-400" />
              </div>

              {/* 컴포넌트 내용 */}
              <div className="flex flex-1 items-center justify-center p-1">
                <ComponentPreview component={comp} />
              </div>

              {/* 삭제 버튼 */}
              {selectedComponentId === comp.id && (
                <Button
                  variant="ghost"
                  size="icon"
                  className="absolute -right-2 -top-2 h-5 w-5 rounded-full bg-white shadow text-destructive hover:bg-destructive/10 z-10"
                  onClick={(e) => {
                    e.stopPropagation();
                    onDeleteComponent(section.id, comp.id);
                  }}
                >
                  <Trash2 className="h-3 w-3" />
                </Button>
              )}
            </div>
          ))}
        </GridLayout>
      )}
    </div>
  );
}

// 컴포넌트 미리보기
interface ComponentPreviewProps {
  component: PopComponentData;
}

function ComponentPreview({ component }: ComponentPreviewProps) {
  const { type, label } = component;

  // 타입별 미리보기 렌더링
  const renderPreview = () => {
    switch (type) {
      case "pop-field":
        return (
          <div className="flex w-full flex-col gap-1">
            <span className="text-[10px] text-gray-500">{label || "필드"}</span>
            <div className="h-6 w-full rounded border border-gray-200 bg-gray-50" />
          </div>
        );
      case "pop-button":
        return (
          <div className="flex h-8 w-full items-center justify-center rounded bg-primary/10 text-primary font-medium">
            {label || "버튼"}
          </div>
        );
      case "pop-list":
        return (
          <div className="flex w-full flex-col gap-0.5">
            <span className="text-[10px] text-gray-500">{label || "리스트"}</span>
            <div className="h-3 w-full rounded bg-gray-100" />
            <div className="h-3 w-3/4 rounded bg-gray-100" />
            <div className="h-3 w-full rounded bg-gray-100" />
          </div>
        );
      case "pop-indicator":
        return (
          <div className="flex w-full flex-col items-center gap-1">
            <span className="text-[10px] text-gray-500">{label || "KPI"}</span>
            <span className="text-lg font-bold text-primary">0</span>
          </div>
        );
      case "pop-scanner":
        return (
          <div className="flex w-full flex-col items-center gap-1">
            <div className="h-8 w-8 rounded border-2 border-dashed border-gray-300 flex items-center justify-center">
              <span className="text-[8px] text-gray-400">QR</span>
            </div>
            <span className="text-[10px] text-gray-500">{label || "스캐너"}</span>
          </div>
        );
      case "pop-numpad":
        return (
          <div className="grid grid-cols-3 gap-0.5 w-full">
            {[1, 2, 3, 4, 5, 6, 7, 8, 9, "C", 0, "OK"].map((key) => (
              <div
                key={key}
                className="flex h-4 items-center justify-center rounded bg-gray-100 text-[8px]"
              >
                {key}
              </div>
            ))}
          </div>
        );
      default:
        return <span className="text-gray-500">{label || type}</span>;
    }
  };

  return <div className="w-full overflow-hidden">{renderPreview()}</div>;
}
