import { useMemo, useRef } from "react";
import type { AppStore } from "@editor/store";
import type { GlobalKeybindConsumer, GlobalPointerConsumer, GlobalWheelConsumer } from "@input/index";
import { canPreviewBrush } from "./canvas/brush";
import { canvasCursorClass } from "./canvas/cursor";
import { useCanvasInput } from "./canvas/useCanvasInput";
import { useCanvasRenderer } from "./canvas/useCanvasRenderer";
import { useCanvasResize } from "./canvas/useCanvasResize";
import { useAppState } from "./useAppState";

const ignoreGlobalKeybind: GlobalKeybindConsumer = () => false;
const ignoreGlobalPointer: GlobalPointerConsumer = () => false;
const ignoreGlobalWheel: GlobalWheelConsumer = () => false;

export type CanvasViewportProps = {
  store: AppStore;
  globalKeybindConsumer?: GlobalKeybindConsumer;
  globalPointerConsumer?: GlobalPointerConsumer;
  globalWheelConsumer?: GlobalWheelConsumer;
};

export function CanvasViewport({
  store,
  globalKeybindConsumer = ignoreGlobalKeybind,
  globalPointerConsumer = ignoreGlobalPointer,
  globalWheelConsumer = ignoreGlobalWheel,
}: CanvasViewportProps) {
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const state = useAppState(store);
  const inputOptions = useMemo(
    () => ({ globalKeybindConsumer, globalPointerConsumer, globalWheelConsumer }),
    [globalKeybindConsumer, globalPointerConsumer, globalWheelConsumer],
  );

  useCanvasRenderer(canvasRef, store);
  useCanvasResize(canvasRef, store.dispatch);
  const input = useCanvasInput(canvasRef, store, inputOptions);
  const hasBrushPreview = Boolean(state.editor.brushPreview && canPreviewBrush(state.document, state.editor));
  const cursorClass = canvasCursorClass(state.editor.tools.interactionMode, input, hasBrushPreview);

  return <canvas ref={canvasRef} className={`h-full w-full ${cursorClass}`} />;
}
