/**
 * 流程设计器主组件
 * 整合节点面板、画布和属性面板
 */

'use client';

import React, { useCallback, useEffect } from 'react';
import {
  DndContext,
  DragEndEvent,
  DragStartEvent,
  MouseSensor,
  TouchSensor,
  useSensor,
  useSensors,
  DragOverlay,
  pointerWithin,
} from '@dnd-kit/core';
import { ReactFlowProvider } from 'reactflow';
import {
  Play,
  Square,
  UserCheck,
  Send,
  GitBranch,
  GitMerge,
} from 'lucide-react';
import { ProcessNodePalette } from './ProcessNodePalette';
import { ProcessCanvas } from './ProcessCanvas';
import { ProcessPropertyPanel } from './ProcessPropertyPanel';
import { useProcessDesignerStore, useCanUndo, useCanRedo } from './useProcessDesignerStore';
import {
  ProcessModel,
  ProcessNodeType,
  ProcessNodeTypeConfig,
  PROCESS_NODE_TYPES,
  generateNodeId,
  createDefaultProcessModel,
} from './types';

// 图标映射
const iconMap: Record<string, React.ElementType> = {
  Play,
  Square,
  UserCheck,
  Send,
  GitBranch,
  GitMerge,
};

// 拖拽叠加层
function DragOverlayContent({ activeId }: { activeId: string | null }) {
  if (!activeId) return null;

  // 从面板拖拽
  if (activeId.startsWith('palette-')) {
    const type = activeId.replace('palette-', '');
    const config = PROCESS_NODE_TYPES.find((f) => f.type === type);
    if (!config) return null;

    const Icon = iconMap[config.icon] || UserCheck;

    return (
      <div className="px-4 py-3 bg-white border-2 border-blue-500 rounded-lg shadow-2xl transform scale-105 animate-pulse">
        <div className="flex items-center gap-2">
          <div
            className="w-7 h-7 rounded-md flex items-center justify-center"
            style={{ backgroundColor: config.color }}
          >
            <Icon className="w-4 h-4 text-white" />
          </div>
          <span className="text-sm font-medium text-gray-800">{config.label}</span>
        </div>
      </div>
    );
  }

  return null;
}

interface ProcessDesignerProps {
  initialModel?: ProcessModel;
  onChange?: (model: ProcessModel) => void;
}

export function ProcessDesigner({ initialModel, onChange }: ProcessDesignerProps) {
  const {
    nodes,
    edges,
    initFromModel,
    reset,
    addNode,
    undo,
    redo,
    toProcessModel,
  } = useProcessDesignerStore();
  
  const canUndo = useCanUndo();
  const canRedo = useCanRedo();
  const [activeId, setActiveId] = React.useState<string | null>(null);

  // 初始化流程模型
  useEffect(() => {
    if (initialModel && initialModel.nodes.length > 0) {
      initFromModel(initialModel);
    } else {
      reset();
    }
  }, [initialModel, initFromModel, reset]);

  // 流程变化时通知外部
  useEffect(() => {
    if (onChange) {
      onChange(toProcessModel());
    }
  }, [nodes, edges, onChange, toProcessModel]);

  // 配置拖拽传感器
  const sensors = useSensors(
    useSensor(MouseSensor, {
      activationConstraint: {
        distance: 5,
      },
    }),
    useSensor(TouchSensor, {
      activationConstraint: {
        delay: 200,
        tolerance: 5,
      },
    })
  );

  // 开始拖拽
  const handleDragStart = useCallback((event: DragStartEvent) => {
    setActiveId(event.active.id as string);
  }, []);

  // 拖拽结束
  const handleDragEnd = useCallback(
    (event: DragEndEvent) => {
      const { active, over } = event;
      setActiveId(null);

      if (!over) return;

      const activeData = active.data.current;

      // 从面板拖拽到画布
      if (activeData?.type === 'palette-node' && over.id === 'process-canvas') {
        const config = activeData.config as ProcessNodeTypeConfig;
        
        // 计算放置位置（可以从 event 中获取更精确的位置）
        const position = {
          x: 250,
          y: 150 + nodes.length * 100,
        };

        addNode({
          id: generateNodeId(),
          type: config.type,
          name: config.label,
          position,
          config: config.defaultConfig,
        });
      }
    },
    [addNode, nodes.length]
  );

  // 处理从画布内部添加节点
  const handleNodeDrop = useCallback(
    (type: ProcessNodeType, position: { x: number; y: number }) => {
      const config = PROCESS_NODE_TYPES.find((c) => c.type === type);
      if (!config) return;

      addNode({
        id: generateNodeId(),
        type: config.type,
        name: config.label,
        position,
        config: config.defaultConfig,
      });
    },
    [addNode]
  );

  // 键盘快捷键
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      // Ctrl/Cmd + Z: 撤销
      if ((e.ctrlKey || e.metaKey) && e.key === 'z' && !e.shiftKey) {
        e.preventDefault();
        if (canUndo) undo();
      }
      // Ctrl/Cmd + Shift + Z 或 Ctrl/Cmd + Y: 重做
      if ((e.ctrlKey || e.metaKey) && (e.key === 'y' || (e.key === 'z' && e.shiftKey))) {
        e.preventDefault();
        if (canRedo) redo();
      }
    };

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

  return (
    <DndContext
      sensors={sensors}
      collisionDetection={pointerWithin}
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
    >
      <ReactFlowProvider>
        <div className="flex h-full bg-gray-100">
          {/* 左侧：节点面板 */}
          <ProcessNodePalette />

          {/* 中间：设计画布 */}
          <ProcessCanvas onNodeDrop={handleNodeDrop} />

          {/* 右侧：属性面板 */}
          <ProcessPropertyPanel />
        </div>
      </ReactFlowProvider>

      {/* 拖拽叠加层 */}
      <DragOverlay>
        <DragOverlayContent activeId={activeId} />
      </DragOverlay>
    </DndContext>
  );
}

export default ProcessDesigner;
