"use client";

import { useState, useCallback, useRef } from "react";
import {
  ScreenDefinition,
  ComponentData,
  LayoutData,
  Position,
  ScreenResolution,
  SCREEN_RESOLUTIONS,
} from "@/types/screen";
import { generateComponentId } from "@/lib/utils/generateId";
import { screenApi } from "@/lib/api/screen";
import { toast } from "sonner";
import { showErrorToast } from "@/lib/utils/toastUtils";
import { RealtimePreview } from "./RealtimePreviewDynamic";
import DesignerToolbar from "./DesignerToolbar";

interface SimpleScreenDesignerProps {
  selectedScreen: ScreenDefinition | null;
  onBackToList: () => void;
}

export default function SimpleScreenDesigner({ selectedScreen, onBackToList }: SimpleScreenDesignerProps) {
  const [layout, setLayout] = useState<LayoutData>({
    components: [],
  });
  const [isSaving, setIsSaving] = useState(false);
  const [screenResolution, setScreenResolution] = useState<ScreenResolution>(SCREEN_RESOLUTIONS[0]);
  const [selectedComponent, setSelectedComponent] = useState<ComponentData | null>(null);

  // 드래그 상태
  const [dragState, setDragState] = useState({
    isDragging: false,
    draggedComponent: null as ComponentData | null,
    originalPosition: { x: 0, y: 0, z: 1 },
    currentPosition: { x: 0, y: 0, z: 1 },
    grabOffset: { x: 0, y: 0 },
  });

  const canvasRef = useRef<HTMLDivElement>(null);

  // 레이아웃 저장
  const handleSave = useCallback(async () => {
    if (!selectedScreen?.screenId) return;

    setIsSaving(true);
    try {
      const layoutWithResolution = {
        ...layout,
        screenResolution: screenResolution,
      };
      await screenApi.saveLayout(selectedScreen.screenId, layoutWithResolution);
      toast.success("화면이 저장되었습니다.");
    } catch (error) {
      // console.error("저장 실패:", error);
      showErrorToast("화면 설정 저장에 실패했습니다", error, { guidance: "잠시 후 다시 시도해 주세요." });
    } finally {
      setIsSaving(false);
    }
  }, [selectedScreen?.screenId, layout, screenResolution]);

  // 컴포넌트 추가
  const addComponent = useCallback((type: ComponentData["type"], position: Position) => {
    const newComponent: ComponentData = {
      id: generateComponentId(),
      type: type,
      position: position,
      size: { width: 200, height: 80 },
      title: `새 ${type}`,
      ...(type === "widget" && {
        webType: "text" as const,
        label: "라벨",
        placeholder: "입력하세요",
      }),
    } as ComponentData;

    setLayout((prev) => ({
      ...prev,
      components: [...prev.components, newComponent],
    }));
  }, []);

  // 드래그 시작
  const startDrag = useCallback((component: ComponentData, event: React.MouseEvent) => {
    event.preventDefault();
    const rect = canvasRef.current?.getBoundingClientRect();
    if (!rect) return;

    setDragState({
      isDragging: true,
      draggedComponent: component,
      originalPosition: component.position,
      currentPosition: component.position,
      grabOffset: {
        x: event.clientX - rect.left - component.position.x,
        y: event.clientY - rect.top - component.position.y,
      },
    });
  }, []);

  // 드래그 업데이트
  const updateDragPosition = useCallback(
    (event: MouseEvent) => {
      if (!dragState.isDragging || !dragState.draggedComponent || !canvasRef.current) return;

      const rect = canvasRef.current.getBoundingClientRect();
      const newPosition = {
        x: Math.max(0, event.clientX - rect.left - dragState.grabOffset.x),
        y: Math.max(0, event.clientY - rect.top - dragState.grabOffset.y),
        z: dragState.draggedComponent.position.z || 1,
      };

      setDragState((prev) => ({
        ...prev,
        currentPosition: newPosition,
      }));
    },
    [dragState],
  );

  // 드래그 종료
  const endDrag = useCallback(() => {
    if (!dragState.isDragging || !dragState.draggedComponent) return;

    const updatedComponents = layout.components.map((comp) =>
      comp.id === dragState.draggedComponent!.id ? { ...comp, position: dragState.currentPosition } : comp,
    );

    setLayout((prev) => ({
      ...prev,
      components: updatedComponents,
    }));

    setDragState({
      isDragging: false,
      draggedComponent: null,
      originalPosition: { x: 0, y: 0, z: 1 },
      currentPosition: { x: 0, y: 0, z: 1 },
      grabOffset: { x: 0, y: 0 },
    });
  }, [dragState, layout.components]);

  // 마우스 이벤트 리스너
  const handleMouseMove = useCallback(
    (event: MouseEvent) => {
      updateDragPosition(event);
    },
    [updateDragPosition],
  );

  const handleMouseUp = useCallback(() => {
    endDrag();
  }, [endDrag]);

  // 이벤트 리스너 등록
  React.useEffect(() => {
    if (dragState.isDragging) {
      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);
      return () => {
        document.removeEventListener("mousemove", handleMouseMove);
        document.removeEventListener("mouseup", handleMouseUp);
      };
    }
  }, [dragState.isDragging, handleMouseMove, handleMouseUp]);

  // 캔버스 클릭 처리
  const handleCanvasClick = useCallback((e: React.MouseEvent) => {
    if (e.target === e.currentTarget) {
      setSelectedComponent(null);
    }
  }, []);

  // 툴바 액션들
  const handleAddText = () => addComponent("widget", { x: 50, y: 50, z: 1 });
  const handleAddContainer = () => addComponent("container", { x: 100, y: 100, z: 1 });

  if (!selectedScreen) {
    return (
      <div className="flex h-screen items-center justify-center">
        <p>화면을 선택해주세요.</p>
      </div>
    );
  }

  return (
    <div className="flex h-screen w-full flex-col bg-muted">
      {/* 상단 툴바 */}
      <DesignerToolbar
        screenName={selectedScreen?.screenName}
        tableName={selectedScreen?.tableName}
        onBack={onBackToList}
        onSave={handleSave}
        onUndo={() => {}}
        onRedo={() => {}}
        onPreview={() => toast.info("미리보기 기능은 준비 중입니다.")}
        onTogglePanel={() => {}}
        panelStates={{}}
        canUndo={false}
        canRedo={false}
        isSaving={isSaving}
      />

      {/* 간단한 컨트롤 버튼들 */}
      <div className="border-b border-input bg-white p-4">
        <div className="flex gap-2">
          <button onClick={handleAddText} className="rounded bg-accent0 px-3 py-1 text-white hover:bg-primary">
            텍스트 추가
          </button>
          <button onClick={handleAddContainer} className="rounded bg-emerald-500 px-3 py-1 text-white hover:bg-emerald-600">
            컨테이너 추가
          </button>
        </div>
      </div>

      {/* 메인 캔버스 영역 */}
      <div className="relative flex-1 overflow-auto bg-muted p-8">
        {/* 해상도 정보 표시 */}
        <div className="mb-4 flex items-center justify-center">
          <div className="rounded-lg border bg-white px-4 py-2 shadow-sm">
            <span className="text-sm font-medium text-foreground">
              {screenResolution.name} ({screenResolution.width} × {screenResolution.height})
            </span>
          </div>
        </div>

        {/* 실제 작업 캔버스 */}
        <div
          className="mx-auto bg-white shadow-lg"
          style={{ width: screenResolution.width, height: screenResolution.height }}
        >
          <div ref={canvasRef} className="relative h-full w-full overflow-hidden bg-white" onClick={handleCanvasClick}>
            {/* 컴포넌트들 */}
            {layout.components.map((component) => (
              <RealtimePreview
                key={component.id}
                component={component}
                isSelected={selectedComponent?.id === component.id}
                onSelect={(comp) => setSelectedComponent(comp)}
                onStartDrag={(comp, event) => startDrag(comp, event)}
                onUpdateComponent={(updates) => {
                  setLayout((prev) => ({
                    ...prev,
                    components: prev.components.map((c) => (c.id === component.id ? { ...c, ...updates } : c)),
                  }));
                }}
                dragPosition={
                  dragState.isDragging && dragState.draggedComponent?.id === component.id
                    ? dragState.currentPosition
                    : undefined
                }
                hideLabel={false}
              />
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}
