"use client";

/**
 * 노드 기반 플로우 에디터 메인 컴포넌트
 */

import { useCallback, useRef, useEffect, useState, useMemo } from "react";
import ReactFlow, { Background, Controls, MiniMap, Panel, ReactFlowProvider, useReactFlow } from "reactflow";
import "reactflow/dist/style.css";

import { useFlowEditorStore } from "@/lib/stores/flowEditorStore";
import { apiClient } from "@/lib/api/client";
import { NodePalette } from "./sidebar/NodePalette";
import { LeftV2Toolbar, ToolbarButton } from "@/components/screen/toolbar/LeftV2Toolbar";
import { Boxes, Settings } from "lucide-react";
import { PropertiesPanel } from "./panels/PropertiesPanel";
import { ValidationNotification } from "./ValidationNotification";
import { FlowToolbar } from "./FlowToolbar";
import { TableSourceNode } from "./nodes/TableSourceNode";
import { ExternalDBSourceNode } from "./nodes/ExternalDBSourceNode";
import { ConditionNode } from "./nodes/ConditionNode";
import { InsertActionNode } from "./nodes/InsertActionNode";
import { UpdateActionNode } from "./nodes/UpdateActionNode";
import { DeleteActionNode } from "./nodes/DeleteActionNode";
import { UpsertActionNode } from "./nodes/UpsertActionNode";
import { DataTransformNode } from "./nodes/DataTransformNode";
import { AggregateNode } from "./nodes/AggregateNode";
import { FormulaTransformNode } from "./nodes/FormulaTransformNode";
import { RestAPISourceNode } from "./nodes/RestAPISourceNode";
import { CommentNode } from "./nodes/CommentNode";
import { LogNode } from "./nodes/LogNode";
import { EmailActionNode } from "./nodes/EmailActionNode";
import { ScriptActionNode } from "./nodes/ScriptActionNode";
import { HttpRequestActionNode } from "./nodes/HttpRequestActionNode";
import { ProcedureCallActionNode } from "./nodes/ProcedureCallActionNode";
import { validateFlow } from "@/lib/utils/flowValidation";
import type { FlowValidation } from "@/lib/utils/flowValidation";

// 노드 타입들
const nodeTypes = {
  // 데이터 소스
  tableSource: TableSourceNode,
  externalDBSource: ExternalDBSourceNode,
  restAPISource: RestAPISourceNode,
  // 변환/조건
  condition: ConditionNode,
  dataTransform: DataTransformNode,
  aggregate: AggregateNode,
  formulaTransform: FormulaTransformNode,
  // 데이터 액션
  insertAction: InsertActionNode,
  updateAction: UpdateActionNode,
  deleteAction: DeleteActionNode,
  upsertAction: UpsertActionNode,
  // 외부 연동 액션
  emailAction: EmailActionNode,
  scriptAction: ScriptActionNode,
  httpRequestAction: HttpRequestActionNode,
  procedureCallAction: ProcedureCallActionNode,
  // 유틸리티
  comment: CommentNode,
  log: LogNode,
};

/**
 * FlowEditor 내부 컴포넌트
 */
interface FlowEditorInnerProps {
  initialFlowId?: number | null;
  /** 임베디드 모드에서 저장 완료 시 호출되는 콜백 */
  onSaveComplete?: (flowId: number, flowName: string) => void;
  /** 임베디드 모드 여부 */
  embedded?: boolean;
}

// 플로우 에디터 툴바 버튼 설정
const flowToolbarButtons: ToolbarButton[] = [
  {
    id: "nodes",
    label: "노드",
    icon: <Boxes className="h-5 w-5" />,
    shortcut: "N",
    group: "source",
    panelWidth: 300,
  },
  {
    id: "properties",
    label: "속성",
    icon: <Settings className="h-5 w-5" />,
    shortcut: "P",
    group: "editor",
    panelWidth: 350,
  },
];

function FlowEditorInner({ initialFlowId, onSaveComplete, embedded = false }: FlowEditorInnerProps) {
  const reactFlowWrapper = useRef<HTMLDivElement>(null);
  const { screenToFlowPosition, setCenter } = useReactFlow();

  // 패널 표시 상태
  const [showNodesPanel, setShowNodesPanel] = useState(true);
  const [showPropertiesPanelLocal, setShowPropertiesPanelLocal] = useState(false);

  const {
    nodes,
    edges,
    onNodesChange,
    onEdgesChange,
    onConnect,
    onNodeDragStart,
    addNode,
    selectNodes,
    selectedNodes,
    removeNodes,
    undo,
    redo,
    loadFlow,
  } = useFlowEditorStore();

  // 🆕 실시간 플로우 검증
  const validations = useMemo<FlowValidation[]>(() => {
    return validateFlow(nodes, edges);
  }, [nodes, edges]);

  // 🆕 노드 클릭 핸들러 (검증 패널에서 사용)
  const handleValidationNodeClick = useCallback(
    (nodeId: string) => {
      const node = nodes.find((n) => n.id === nodeId);
      if (node) {
        selectNodes([nodeId]);
        setCenter(node.position.x + 125, node.position.y + 50, {
          zoom: 1.5,
          duration: 500,
        });
      }
    },
    [nodes, selectNodes, setCenter],
  );

  // 속성 패널 상태 동기화
  useEffect(() => {
    if (selectedNodes.length > 0 && !showPropertiesPanelLocal) {
      setShowPropertiesPanelLocal(true);
    }
  }, [selectedNodes, showPropertiesPanelLocal]);

  // 초기 플로우 로드
  useEffect(() => {
    const fetchAndLoadFlow = async () => {
      if (initialFlowId) {
        try {
          const response = await apiClient.get(`/dataflow/node-flows/${initialFlowId}`);

          if (response.data.success && response.data.data) {
            const flow = response.data.data;
            const flowData = typeof flow.flowData === "string" ? JSON.parse(flow.flowData) : flow.flowData;

            loadFlow(
              flow.flowId,
              flow.flowName,
              flow.flowDescription || "",
              flowData.nodes || [],
              flowData.edges || [],
            );

            // 🆕 플로우 로드 후 첫 번째 노드 자동 선택
            if (flowData.nodes && flowData.nodes.length > 0) {
              const firstNode = flowData.nodes[0];
              selectNodes([firstNode.id]);
              setShowPropertiesPanelLocal(true);
              console.log("✅ 첫 번째 노드 자동 선택:", firstNode.id);
            }
          }
        } catch (error) {
          console.error("플로우 로드 실패:", error);
        }
      }
    };

    fetchAndLoadFlow();
  }, [initialFlowId, loadFlow, selectNodes]);

  /**
   * 노드 선택 변경 핸들러
   */
  const onSelectionChange = useCallback(
    ({ nodes: selectedNodes }: { nodes: any[] }) => {
      const selectedIds = selectedNodes.map((node) => node.id);
      selectNodes(selectedIds);
      console.log("🔍 선택된 노드:", selectedIds);
    },
    [selectNodes],
  );

  /**
   * 키보드 이벤트 핸들러 (Delete/Backspace 키로 노드 삭제, Ctrl+Z/Y로 Undo/Redo)
   */
  const onKeyDown = useCallback(
    (event: React.KeyboardEvent) => {
      // Undo: Ctrl+Z (Windows/Linux) or Cmd+Z (Mac)
      if ((event.ctrlKey || event.metaKey) && event.key === "z" && !event.shiftKey) {
        event.preventDefault();
        console.log("⏪ Undo");
        undo();
        return;
      }

      // Redo: Ctrl+Y (Windows/Linux) or Cmd+Shift+Z (Mac) or Ctrl+Shift+Z
      if (
        ((event.ctrlKey || event.metaKey) && event.key === "y") ||
        ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === "z")
      ) {
        event.preventDefault();
        console.log("⏩ Redo");
        redo();
        return;
      }

      // Delete: Delete/Backspace 키로 노드 삭제
      if ((event.key === "Delete" || event.key === "Backspace") && selectedNodes.length > 0) {
        event.preventDefault();
        console.log("🗑️ 선택된 노드 삭제:", selectedNodes);
        removeNodes(selectedNodes);
      }
    },
    [selectedNodes, removeNodes, undo, redo],
  );

  /**
   * 드래그 앤 드롭 핸들러
   */
  const onDragOver = useCallback((event: React.DragEvent) => {
    event.preventDefault();
    event.dataTransfer.dropEffect = "move";
  }, []);

  const onDrop = useCallback(
    (event: React.DragEvent) => {
      event.preventDefault();

      const type = event.dataTransfer.getData("application/reactflow");
      if (!type) return;

      const position = screenToFlowPosition({
        x: event.clientX,
        y: event.clientY,
      });

      // 🔥 노드 타입별 기본 데이터 설정
      const defaultData: any = {
        displayName: `새 ${type} 노드`,
      };

      // REST API 소스 노드의 경우
      if (type === "restAPISource") {
        defaultData.method = "GET";
        defaultData.url = "";
        defaultData.headers = {};
        defaultData.timeout = 30000;
        defaultData.responseFields = []; // 빈 배열로 초기화
        defaultData.responseMapping = "";
      }

      // 데이터 액션 노드의 경우 targetType 기본값 설정
      if (["insertAction", "updateAction", "deleteAction", "upsertAction"].includes(type)) {
        defaultData.targetType = "internal"; // 기본값: 내부 DB
        defaultData.fieldMappings = [];
        defaultData.options = {};

        if (type === "updateAction" || type === "deleteAction") {
          defaultData.whereConditions = [];
        }

        if (type === "upsertAction") {
          defaultData.conflictKeys = [];
        }
      }

      // 메일 발송 노드
      if (type === "emailAction") {
        defaultData.displayName = "메일 발송";
        defaultData.smtpConfig = {
          host: "",
          port: 587,
          secure: false,
        };
        defaultData.from = "";
        defaultData.to = "";
        defaultData.subject = "";
        defaultData.body = "";
        defaultData.bodyType = "text";
      }

      // 스크립트 실행 노드
      if (type === "scriptAction") {
        defaultData.displayName = "스크립트 실행";
        defaultData.scriptType = "python";
        defaultData.executionMode = "inline";
        defaultData.inlineScript = "";
        defaultData.inputMethod = "stdin";
        defaultData.inputFormat = "json";
        defaultData.outputHandling = {
          captureStdout: true,
          captureStderr: true,
          parseOutput: "text",
        };
      }

      // HTTP 요청 노드
      if (type === "httpRequestAction") {
        defaultData.displayName = "HTTP 요청";
        defaultData.url = "";
        defaultData.method = "GET";
        defaultData.bodyType = "none";
        defaultData.authentication = { type: "none" };
        defaultData.options = {
          timeout: 30000,
          followRedirects: true,
        };
      }

      const newNode: any = {
        id: `node_${Date.now()}`,
        type,
        position,
        data: defaultData,
      };

      addNode(newNode);
    },
    [screenToFlowPosition, addNode],
  );

  return (
    <div className="flex h-full w-full" style={{ height: "100%", overflow: "hidden" }}>
      {/* 좌측 통합 툴바 */}
      <LeftV2Toolbar
        buttons={flowToolbarButtons}
        panelStates={{
          nodes: { isOpen: showNodesPanel },
          properties: { isOpen: showPropertiesPanelLocal },
        }}
        onTogglePanel={(panelId) => {
          if (panelId === "nodes") {
            setShowNodesPanel(!showNodesPanel);
          } else if (panelId === "properties") {
            setShowPropertiesPanelLocal(!showPropertiesPanelLocal);
          }
        }}
      />

      {/* 노드 라이브러리 패널 */}
      {showNodesPanel && (
        <div className="h-full w-[300px] border-r bg-white">
          <NodePalette />
        </div>
      )}

      {/* 중앙 캔버스 */}
      <div className="relative flex-1" ref={reactFlowWrapper} onKeyDown={onKeyDown} tabIndex={0}>
        <ReactFlow
          nodes={nodes as any}
          edges={edges as any}
          onNodesChange={onNodesChange}
          onEdgesChange={onEdgesChange}
          onConnect={onConnect}
          onNodeDragStart={onNodeDragStart}
          onSelectionChange={onSelectionChange}
          onDragOver={onDragOver}
          onDrop={onDrop}
          nodeTypes={nodeTypes}
          fitView
          className="bg-muted"
          deleteKeyCode={["Delete", "Backspace"]}
        >
          {/* 배경 그리드 */}
          <Background gap={16} size={1} color="#E5E7EB" />

          {/* 컨트롤 버튼 */}
          <Controls className="bg-white shadow-md" />

          {/* 미니맵 */}
          <MiniMap
            className="bg-white shadow-md"
            nodeColor={(node) => {
              // 노드 타입별 색상 (추후 구현)
              return "#3B82F6";
            }}
            maskColor="rgba(0, 0, 0, 0.1)"
          />

          {/* 상단 툴바 */}
          <Panel position="top-center" className="pointer-events-auto">
            <FlowToolbar validations={validations} onSaveComplete={onSaveComplete} />
          </Panel>
        </ReactFlow>
      </div>

      {/* 우측 속성 패널 */}
      {showPropertiesPanelLocal && selectedNodes.length > 0 && (
        <div
          style={{
            height: "100%",
            width: "350px",
            display: "flex",
            flexDirection: "column",
          }}
          className="border-l bg-white"
        >
          <PropertiesPanel />
        </div>
      )}

      {/* 검증 알림 (우측 상단 플로팅) */}
      <ValidationNotification validations={validations} onNodeClick={handleValidationNodeClick} />
    </div>
  );
}

/**
 * FlowEditor 메인 컴포넌트 (Provider로 감싸기)
 */
interface FlowEditorProps {
  initialFlowId?: number | null;
  /** 임베디드 모드에서 저장 완료 시 호출되는 콜백 */
  onSaveComplete?: (flowId: number, flowName: string) => void;
  /** 임베디드 모드 여부 (헤더 표시 여부 등) */
  embedded?: boolean;
}

export function FlowEditor({ initialFlowId, onSaveComplete, embedded = false }: FlowEditorProps = {}) {
  return (
    <div className="h-full w-full">
      <ReactFlowProvider>
        <FlowEditorInner 
          initialFlowId={initialFlowId} 
          onSaveComplete={onSaveComplete}
          embedded={embedded}
        />
      </ReactFlowProvider>
    </div>
  );
}
