/**
 * Canvas host: mounts the JointJS paper via EditorController and accepts
 * palette drops.
 */

import { useEffect, useRef } from 'react';
import { EditorController } from '../editor/paper';
import { PALETTE_MIME } from './Palette';
import { getState, setState, bumpGraphVersion, applySimulationResult } from '../state/store';

interface CanvasProps {
  onReady(controller: EditorController): void;
}

export function Canvas({ onReady }: CanvasProps) {
  const hostRef = useRef<HTMLDivElement>(null);
  const controllerRef = useRef<EditorController | null>(null);

  useEffect(() => {
    const host = hostRef.current;
    if (!host || controllerRef.current) return;
    const controller = new EditorController(host, getState().config, {
      onSelectionChange: (selection) => setState({ selection }),
      onGraphChange: () => bumpGraphVersion(),
      onHistoryChange: (canUndo, canRedo) => setState({ canUndo, canRedo }),
      onSimulationChange: (running, result) => applySimulationResult(running, result),
    });
    controllerRef.current = controller;
    onReady(controller);
    return () => {
      controller.dispose();
      controllerRef.current = null;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div
      ref={hostRef}
      className="pf-canvas"
      data-testid="canvas"
      onDragOver={(e) => {
        if (e.dataTransfer.types.includes(PALETTE_MIME)) {
          e.preventDefault();
          e.dataTransfer.dropEffect = 'copy';
        }
      }}
      onDrop={(e) => {
        const typeId = e.dataTransfer.getData(PALETTE_MIME);
        const controller = controllerRef.current;
        if (!typeId || !controller) return;
        e.preventDefault();
        const p = controller.clientToLocal(e.clientX, e.clientY);
        controller.addNode(typeId, p.x, p.y);
      }}
    />
  );
}
