"use client";

import React, { forwardRef, useState, useCallback, useMemo } from "react";
import { DashboardElement, ElementType, ElementSubtype, DragData } from "./types";
import { CanvasElement } from "./CanvasElement";
import { GRID_CONFIG, snapToGrid, calculateGridConfig } from "./gridUtils";

interface DashboardCanvasProps {
  elements: DashboardElement[];
  selectedElement: string | null;
  onCreateElement: (type: ElementType, subtype: ElementSubtype, x: number, y: number) => void;
  onUpdateElement: (id: string, updates: Partial<DashboardElement>) => void;
  onRemoveElement: (id: string) => void;
  onSelectElement: (id: string | null) => void;
  onConfigureElement?: (element: DashboardElement) => void;
  backgroundColor?: string;
  canvasWidth?: number;
  canvasHeight?: number;
}

/**
 * 대시보드 캔버스 컴포넌트
 * - 드래그 앤 드롭 영역
 * - 12 컬럼 그리드 배경
 * - 스냅 기능
 * - 요소 배치 및 관리
 */
export const DashboardCanvas = forwardRef<HTMLDivElement, DashboardCanvasProps>(
  (
    {
      elements,
      selectedElement,
      onCreateElement,
      onUpdateElement,
      onRemoveElement,
      onSelectElement,
      onConfigureElement,
      backgroundColor = "#f9fafb",
      canvasWidth = 1560,
      canvasHeight = 768,
    },
    ref,
  ) => {
    const [isDragOver, setIsDragOver] = useState(false);

    // 현재 캔버스 크기에 맞는 그리드 설정 계산
    const gridConfig = useMemo(() => calculateGridConfig(canvasWidth), [canvasWidth]);
    const cellSize = gridConfig.CELL_SIZE;

    // 드래그 오버 처리
    const handleDragOver = useCallback((e: React.DragEvent) => {
      e.preventDefault();
      e.dataTransfer.dropEffect = "copy";
      setIsDragOver(true);
    }, []);

    // 드래그 리브 처리
    const handleDragLeave = useCallback((e: React.DragEvent) => {
      if (e.currentTarget === e.target) {
        setIsDragOver(false);
      }
    }, []);

    // 드롭 처리 (그리드 스냅 적용)
    const handleDrop = useCallback(
      (e: React.DragEvent) => {
        e.preventDefault();
        setIsDragOver(false);

        try {
          const dragData: DragData = JSON.parse(e.dataTransfer.getData("application/json"));

          if (!ref || typeof ref === "function") return;

          const rect = ref.current?.getBoundingClientRect();
          if (!rect) return;

          // 캔버스 스크롤을 고려한 정확한 위치 계산
          const rawX = e.clientX - rect.left + (ref.current?.scrollLeft || 0);
          const rawY = e.clientY - rect.top + (ref.current?.scrollTop || 0);

          // 그리드에 스냅 (동적 셀 크기 사용)
          let snappedX = snapToGrid(rawX, cellSize);
          const snappedY = snapToGrid(rawY, cellSize);

          // X 좌표가 캔버스 너비를 벗어나지 않도록 제한
          const maxX = canvasWidth - cellSize * 2; // 최소 2칸 너비 보장
          snappedX = Math.max(0, Math.min(snappedX, maxX));

          onCreateElement(dragData.type, dragData.subtype, snappedX, snappedY);
        } catch {
          // 드롭 데이터 파싱 오류 무시
        }
      },
      [ref, onCreateElement, canvasWidth, cellSize],
    );

    // 캔버스 클릭 시 선택 해제
    const handleCanvasClick = useCallback(
      (e: React.MouseEvent) => {
        if (e.target === e.currentTarget) {
          onSelectElement(null);
        }
      },
      [onSelectElement],
    );

    // 동적 그리드 크기 계산
    const cellWithGap = cellSize + GRID_CONFIG.GAP;
    const gridSize = `${cellWithGap}px ${cellWithGap}px`;

    // 12개 컬럼 구분선 위치 계산
    const columnLines = Array.from({ length: GRID_CONFIG.COLUMNS + 1 }, (_, i) => i * cellWithGap);

    return (
      <div
        ref={ref}
        className={`relative w-full rounded-lg shadow-inner ${isDragOver ? "bg-blue-50/50" : ""} `}
        style={{
          backgroundColor,
          height: `${canvasHeight}px`,
          minHeight: `${canvasHeight}px`,
          // 세밀한 그리드 배경
          backgroundImage: `
            linear-gradient(rgba(59, 130, 246, 0.08) 1px, transparent 1px),
            linear-gradient(90deg, rgba(59, 130, 246, 0.08) 1px, transparent 1px)
          `,
          backgroundSize: gridSize,
          backgroundPosition: "0 0",
          backgroundRepeat: "repeat",
        }}
        onDragOver={handleDragOver}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
        onClick={handleCanvasClick}
      >
        {/* 12개 컬럼 메인 구분선 */}
        {columnLines.map((x, i) => (
          <div
            key={`col-${i}`}
            className="pointer-events-none absolute top-0 h-full"
            style={{
              left: `${x}px`,
              width: "2px",
              zIndex: 1,
            }}
          />
        ))}
        {/* 배치된 요소들 렌더링 */}
        {elements.length === 0 && (
          <div className="pointer-events-none absolute inset-0 flex items-center justify-center text-gray-400">
            <div className="text-center">
              <div className="text-sm">상단 메뉴에서 차트나 위젯을 선택하세요</div>
            </div>
          </div>
        )}
        {elements.map((element) => (
          <CanvasElement
            key={element.id}
            element={element}
            isSelected={selectedElement === element.id}
            cellSize={cellSize}
            canvasWidth={canvasWidth}
            onUpdate={onUpdateElement}
            onRemove={onRemoveElement}
            onSelect={onSelectElement}
            onConfigure={onConfigureElement}
          />
        ))}
      </div>
    );
  },
);

DashboardCanvas.displayName = "DashboardCanvas";
