"use client";

import { useState, useCallback, useEffect } from "react";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
import { ArrowLeft, Save, Undo2, Redo2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable";
import { toast } from "sonner";

import PopCanvas from "./PopCanvas";
import ComponentEditorPanel from "./panels/ComponentEditorPanel";
import ComponentPalette from "./panels/ComponentPalette";
import {
  PopLayoutDataV5,
  PopComponentType,
  PopComponentDefinitionV5,
  PopGridPosition,
  GridMode,
  createEmptyPopLayoutV5,
  isV5Layout,
  addComponentToV5Layout,
} from "./types/pop-layout";
import { screenApi } from "@/lib/api/screen";
import { ScreenDefinition } from "@/types/screen";

// ========================================
// Props
// ========================================
interface PopDesignerProps {
  selectedScreen: ScreenDefinition;
  onBackToList: () => void;
  onScreenUpdate?: (updatedScreen: Partial<ScreenDefinition>) => void;
}

// ========================================
// 메인 컴포넌트 (v5 그리드 시스템 전용)
// ========================================
export default function PopDesigner({
  selectedScreen,
  onBackToList,
  onScreenUpdate,
}: PopDesignerProps) {
  // ========================================
  // 레이아웃 상태
  // ========================================
  const [layout, setLayout] = useState<PopLayoutDataV5>(createEmptyPopLayoutV5());

  // 히스토리
  const [history, setHistory] = useState<PopLayoutDataV5[]>([]);
  const [historyIndex, setHistoryIndex] = useState(-1);

  // UI 상태
  const [isLoading, setIsLoading] = useState(true);
  const [isSaving, setIsSaving] = useState(false);
  const [hasChanges, setHasChanges] = useState(false);
  const [idCounter, setIdCounter] = useState(1);

  // 선택 상태
  const [selectedComponentId, setSelectedComponentId] = useState<string | null>(null);

  // 그리드 모드 (4개 프리셋)
  const [currentMode, setCurrentMode] = useState<GridMode>("tablet_landscape");

  // 선택된 컴포넌트
  const selectedComponent: PopComponentDefinitionV5 | null = selectedComponentId
    ? layout.components[selectedComponentId] || null
    : null;

  // ========================================
  // 히스토리 관리
  // ========================================
  const saveToHistory = useCallback((newLayout: PopLayoutDataV5) => {
    setHistory((prev) => {
      const newHistory = prev.slice(0, historyIndex + 1);
      newHistory.push(JSON.parse(JSON.stringify(newLayout)));
      // 최대 50개 유지
      if (newHistory.length > 50) {
        newHistory.shift();
        return newHistory;
      }
      return newHistory;
    });
    setHistoryIndex((prev) => Math.min(prev + 1, 49));
  }, [historyIndex]);

  const undo = useCallback(() => {
    if (historyIndex > 0) {
      const newIndex = historyIndex - 1;
      const previousLayout = history[newIndex];
      if (previousLayout) {
        setLayout(JSON.parse(JSON.stringify(previousLayout)));
        setHistoryIndex(newIndex);
        setHasChanges(true);
        toast.success("실행 취소됨");
      }
    }
  }, [historyIndex, history]);

  const redo = useCallback(() => {
    if (historyIndex < history.length - 1) {
      const newIndex = historyIndex + 1;
      const nextLayout = history[newIndex];
      if (nextLayout) {
        setLayout(JSON.parse(JSON.stringify(nextLayout)));
        setHistoryIndex(newIndex);
        setHasChanges(true);
        toast.success("다시 실행됨");
      }
    }
  }, [historyIndex, history]);

  const canUndo = historyIndex > 0;
  const canRedo = historyIndex < history.length - 1;

  // ========================================
  // 레이아웃 로드
  // ========================================
  useEffect(() => {
    const loadLayout = async () => {
      if (!selectedScreen?.screenId) return;

      setIsLoading(true);
      try {
        const loadedLayout = await screenApi.getLayoutPop(selectedScreen.screenId);
        
        if (loadedLayout && isV5Layout(loadedLayout) && Object.keys(loadedLayout.components).length > 0) {
          // v5 레이아웃 로드
          setLayout(loadedLayout);
          setHistory([loadedLayout]);
          setHistoryIndex(0);
          console.log(`POP 레이아웃 로드: ${Object.keys(loadedLayout.components).length}개 컴포넌트`);
        } else {
          // 새 화면 또는 빈 레이아웃
          const emptyLayout = createEmptyPopLayoutV5();
          setLayout(emptyLayout);
          setHistory([emptyLayout]);
          setHistoryIndex(0);
          console.log("새 POP 화면 생성 (v5 그리드)");
        }
      } catch (error) {
        console.error("레이아웃 로드 실패:", error);
        toast.error("레이아웃을 불러오는데 실패했습니다");
        const emptyLayout = createEmptyPopLayoutV5();
        setLayout(emptyLayout);
        setHistory([emptyLayout]);
        setHistoryIndex(0);
      } finally {
        setIsLoading(false);
      }
    };

    loadLayout();
  }, [selectedScreen?.screenId]);

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

    setIsSaving(true);
    try {
      await screenApi.saveLayoutPop(selectedScreen.screenId, layout);
      toast.success("저장되었습니다");
      setHasChanges(false);
    } catch (error) {
      console.error("저장 실패:", error);
      toast.error("저장에 실패했습니다");
    } finally {
      setIsSaving(false);
    }
  }, [selectedScreen?.screenId, layout]);

  // ========================================
  // 컴포넌트 핸들러
  // ========================================
  const handleDropComponent = useCallback(
    (type: PopComponentType, position: PopGridPosition) => {
      const componentId = `comp_${idCounter}`;
      setIdCounter((prev) => prev + 1);
      const newLayout = addComponentToV5Layout(layout, componentId, type, position, `${type} ${idCounter}`);
      setLayout(newLayout);
      saveToHistory(newLayout);
      setSelectedComponentId(componentId);
      setHasChanges(true);
    },
    [idCounter, layout, saveToHistory]
  );

  const handleUpdateComponent = useCallback(
    (componentId: string, updates: Partial<PopComponentDefinitionV5>) => {
      const existingComponent = layout.components[componentId];
      if (!existingComponent) return;

      const newLayout = {
        ...layout,
        components: {
          ...layout.components,
          [componentId]: {
            ...existingComponent,
            ...updates,
          },
        },
      };
      setLayout(newLayout);
      saveToHistory(newLayout);
      setHasChanges(true);
    },
    [layout, saveToHistory]
  );

  const handleDeleteComponent = useCallback(
    (componentId: string) => {
      const newComponents = { ...layout.components };
      delete newComponents[componentId];
      
      const newLayout = {
        ...layout,
        components: newComponents,
      };
      setLayout(newLayout);
      saveToHistory(newLayout);
      setSelectedComponentId(null);
      setHasChanges(true);
    },
    [layout, saveToHistory]
  );

  // ========================================
  // 뒤로가기
  // ========================================
  const handleBack = useCallback(() => {
    if (hasChanges) {
      if (confirm("저장하지 않은 변경사항이 있습니다. 정말 나가시겠습니까?")) {
        onBackToList();
      }
    } else {
      onBackToList();
    }
  }, [hasChanges, onBackToList]);

  // ========================================
  // 단축키 처리
  // ========================================
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      const target = e.target as HTMLElement;
      if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable) {
        return;
      }

      const key = e.key.toLowerCase();
      const isCtrlOrCmd = e.ctrlKey || e.metaKey;

      // Delete / Backspace: 컴포넌트 삭제
      if (e.key === "Delete" || e.key === "Backspace") {
        e.preventDefault();
        if (selectedComponentId) {
          handleDeleteComponent(selectedComponentId);
        }
      }

      // Ctrl+Z: Undo
      if (isCtrlOrCmd && key === "z" && !e.shiftKey) {
        e.preventDefault();
        if (canUndo) undo();
        return;
      }

      // Ctrl+Shift+Z or Ctrl+Y: Redo
      if ((isCtrlOrCmd && key === "z" && e.shiftKey) || (isCtrlOrCmd && key === "y")) {
        e.preventDefault();
        if (canRedo) redo();
        return;
      }

      // Ctrl+S: 저장
      if (isCtrlOrCmd && key === "s") {
        e.preventDefault();
        handleSave();
        return;
      }
    };

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [selectedComponentId, handleDeleteComponent, canUndo, canRedo, undo, redo, handleSave]);

  // ========================================
  // 로딩
  // ========================================
  if (isLoading) {
    return (
      <div className="flex h-screen items-center justify-center">
        <div className="text-muted-foreground">로딩 중...</div>
      </div>
    );
  }

  // ========================================
  // 렌더링
  // ========================================
  return (
    <DndProvider backend={HTML5Backend}>
      <div className="flex h-screen flex-col">
        {/* 헤더 */}
        <div className="flex items-center justify-between border-b bg-white px-4 py-2">
          {/* 왼쪽: 뒤로가기 + 화면명 */}
          <div className="flex items-center gap-3">
            <Button
              variant="ghost"
              size="icon"
              onClick={handleBack}
              className="h-8 w-8"
            >
              <ArrowLeft className="h-4 w-4" />
            </Button>
            <div>
              <h2 className="text-sm font-medium">{selectedScreen?.screenName}</h2>
              <p className="text-xs text-muted-foreground">
                그리드 레이아웃 (v5)
              </p>
            </div>
          </div>

          {/* 오른쪽: Undo/Redo + 저장 */}
          <div className="flex items-center gap-2">
            {/* Undo/Redo 버튼 */}
            <div className="flex items-center gap-1 border-r pr-2 mr-1">
              <Button
                variant="ghost"
                size="icon"
                className="h-8 w-8"
                onClick={undo}
                disabled={!canUndo}
                title="실행 취소 (Ctrl+Z)"
              >
                <Undo2 className="h-4 w-4" />
              </Button>
              <Button
                variant="ghost"
                size="icon"
                className="h-8 w-8"
                onClick={redo}
                disabled={!canRedo}
                title="다시 실행 (Ctrl+Shift+Z)"
              >
                <Redo2 className="h-4 w-4" />
              </Button>
            </div>
            
            {/* 저장 버튼 */}
            <Button size="sm" onClick={handleSave} disabled={isSaving || !hasChanges}>
              <Save className="mr-1 h-4 w-4" />
              {isSaving ? "저장 중..." : "저장"}
            </Button>
          </div>
        </div>

        {/* 메인 영역 */}
        <ResizablePanelGroup direction="horizontal" className="flex-1">
          {/* 왼쪽: 컴포넌트 팔레트 */}
          <ResizablePanel defaultSize={15} minSize={12} maxSize={20}>
            <ComponentPalette />
          </ResizablePanel>

          <ResizableHandle withHandle />

          {/* 중앙: 캔버스 */}
          <ResizablePanel defaultSize={65}>
            <PopCanvas
              layout={layout}
              selectedComponentId={selectedComponentId}
              currentMode={currentMode}
              onModeChange={setCurrentMode}
              onSelectComponent={setSelectedComponentId}
              onDropComponent={handleDropComponent}
              onUpdateComponent={handleUpdateComponent}
              onDeleteComponent={handleDeleteComponent}
            />
          </ResizablePanel>

          <ResizableHandle withHandle />

          {/* 오른쪽: 속성 패널 */}
          <ResizablePanel defaultSize={20} minSize={15} maxSize={30}>
            <ComponentEditorPanel
              component={selectedComponent}
              currentMode={currentMode}
              onUpdateComponent={
                selectedComponentId
                  ? (updates) => handleUpdateComponent(selectedComponentId, updates)
                  : undefined
              }
            />
          </ResizablePanel>
        </ResizablePanelGroup>
      </div>
    </DndProvider>
  );
}
