import React, { useEffect, useMemo, useRef } from 'react';
import ReactFlow, { Controls, Background } from 'reactflow';
import 'reactflow/dist/style.css';
import { debounce } from 'lodash';
import { useFlowChart } from './FlowChartComponents/useFlowChart';
import { useNodeHandlers } from './FlowChartComponents/useNodeHandlers';
import { useDataParser } from './FlowChartComponents/DataParser';
import NodeWrapper from './FlowChartComponents/NodeWrapper';

const nodeTypes = {
  customNode: NodeWrapper
};

const FlowChart = ({ data }) => {
  const {
    nodes,
    edges,
    nodePositions,
    setNodes,
    setEdges,
    onNodesChange,
    onEdgesChange,
    setNodePositions,
    collapsedNodes,
    toggleNodeCollapse
  } = useFlowChart(data);

  const { parseData } = useDataParser(nodePositions, collapsedNodes);
  const initialized = useRef(false);

  const debouncedSetNodePositions = useMemo(
    () => debounce(setNodePositions, 100),
    [setNodePositions]
  );

  const { onNodeDrag, onNodeDragStop } = useNodeHandlers(debouncedSetNodePositions);

  useEffect(() => {
    const { nodes: initialNodes, edges: initialEdges } = parseData(data);
    setNodes(initialNodes);
    setEdges(initialEdges);

    // Автоматически сворачиваем узлы, которые являются родителями последнего уровня
    if (!initialized.current && data) {
      const findAndCollapseLastLevelParents = (items) => {
        items.forEach(item => {
          if (item.items && item.items.length > 0) {
            const hasGrandchildren = item.items.some(child =>
              child.items && child.items.length > 0
            );

            if (!hasGrandchildren) {
              toggleNodeCollapse(item.id);
            } else {
              findAndCollapseLastLevelParents(item.items);
            }
          }
        });
      };

      findAndCollapseLastLevelParents(data.items || []);
      initialized.current = true;
    }
  }, [data, parseData, setNodes, setEdges, toggleNodeCollapse]);

  const onNodeClick = (event, node) => {
    if (node.data.hasChildren) {
      toggleNodeCollapse(node.id);
    }
  };

  useEffect(() => {
    return () => {
      debouncedSetNodePositions.cancel();
    };
  }, [debouncedSetNodePositions]);

  return (
    <div style={{ height: '85vh', width: '100%' }}>
      <ReactFlow
        nodes={nodes}
        edges={edges}
        nodeTypes={nodeTypes}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        onNodeDrag={onNodeDrag}
        onNodeDragStop={onNodeDragStop}
        nodeDragThreshold={1}
        onNodeClick={onNodeClick}
        fitView
      >
        <Background />
        <Controls />
      </ReactFlow>
    </div>
  );
};

export default React.memo(FlowChart);