import { forwardRef, useImperativeHandle, useMemo } from 'react';
import {
  ReactFlow,
  useReactFlow,
  ReactFlowProvider,
  Background,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';

import type { AttributeDAG } from '../types';
import { nodeTypes, useDAGLayout } from './dag';
import '../styles/mindmap.css';

interface VisualSettings {
  nodeSpacing: number;
  fontSize: number;
}

interface MindmapDAGProps {
  data: AttributeDAG;
  isDark: boolean;
  visualSettings: VisualSettings;
}

export interface MindmapDAGRef {
  resetView: () => void;
}

// Inner component that uses useReactFlow
const MindmapDAGInner = forwardRef<MindmapDAGRef, MindmapDAGProps>(
  ({ data, isDark, visualSettings }, ref) => {
    const { setViewport } = useReactFlow();

    // Layout configuration
    const layoutConfig = useMemo(
      () => ({
        nodeHeight: 32,
        headerGap: 12,
        headerHeight: 28,
        nodeSpacing: Math.max(visualSettings.nodeSpacing, 40),
        fontSize: visualSettings.fontSize,
        isDark,
      }),
      [visualSettings.nodeSpacing, visualSettings.fontSize, isDark]
    );

    // Generate nodes with layout
    const nodes = useDAGLayout(data, layoutConfig);

    // Expose resetView via ref
    useImperativeHandle(
      ref,
      () => ({
        resetView: () => {
          setViewport({ x: 50, y: 50, zoom: 1 }, { duration: 300 });
        },
      }),
      [setViewport]
    );

    return (
      <ReactFlow
        nodes={nodes}
        edges={[]}
        nodeTypes={nodeTypes}
        fitView
        fitViewOptions={{ padding: 0.2 }}
        minZoom={0.3}
        maxZoom={3}
        defaultViewport={{ x: 50, y: 50, zoom: 1 }}
        proOptions={{ hideAttribution: true }}
        nodesDraggable={false}
        nodesConnectable={false}
        elementsSelectable={false}
        panOnDrag
        zoomOnScroll
        zoomOnPinch
      >
        <Background
          color={isDark ? '#333' : '#e0e0e0'}
          gap={20}
          size={1}
        />
      </ReactFlow>
    );
  }
);

MindmapDAGInner.displayName = 'MindmapDAGInner';

// Wrapper with ReactFlowProvider
export const MindmapDAG = forwardRef<MindmapDAGRef, MindmapDAGProps>(
  (props, ref) => (
    <div
      className={`mindmap-container ${props.isDark ? 'mindmap-dark' : 'mindmap-light'}`}
    >
      <ReactFlowProvider>
        <MindmapDAGInner {...props} ref={ref} />
      </ReactFlowProvider>
    </div>
  )
);

MindmapDAG.displayName = 'MindmapDAG';
