import gridImage from "#../assets/editor-hover-grid.png";
import clsx from "clsx";
import {
  Accessor,
  Component,
  createMemo,
  Show,
  Suspense,
  useContext,
} from "solid-js";
import { EditorUiContext } from "../../../../lib/context/admin";
import { StateContext } from "../../../../lib/context/page";
import { ROOT_ELEMENT_ID } from "#lib/constants";
import { useCanHover } from "../../lib/element";
import classes from "./handles.module.css";
import Selection from "./selection";

const Handles: Component<{
  elementId: string;
  elementRef: Accessor<HTMLElement | undefined>;
  outline?: "vertical" | "horizontal";
  last?: boolean;
  disabled?: boolean;
}> = (p) => {
  const [state] = useContext(StateContext)!;
  const [editorUi] = useContext(EditorUiContext)!;

  const moveHandleClass = createMemo(function () {
    const element = state.elements[p.elementId];
    const slot = state.slots[element.parentSlotId!];
    return "handle-" + slot?.parentElementId || "root";
  });
  const outline = () => {
    if (editorUi.viewport.tool === "creating" && !editorUi.creatingElementId) {
      return true;
    }
    if (editorUi.viewport.tool === "moving" && editorUi.movingElementId) {
      return true;
    }
    return false;
  };

  const canHover = useCanHover();
  const hovered = createMemo(
    () =>
      (editorUi.hoveredElementId === p.elementId &&
        !editorUi.movingElementId) ||
      p.elementId === editorUi.deletingElementId,
  );

  return (
    <>
      <Show when={outline() && p.outline}>
        <div
          class={clsx(
            classes["outline"],
            classes[
              p.outline === "horizontal" ? "outline--left" : "outline--top"
            ],
          )}
        />
        <Show when={p.last}>
          <div
            class={clsx(
              classes["outline"],
              classes[
                p.outline === "horizontal"
                  ? "outline--right"
                  : "outline--bottom"
              ],
            )}
          />
        </Show>
      </Show>
      <Show
        when={
          state.elements[p.elementId]?.blueprintId !== "root" &&
          (hovered() || canHover())
        }
      >
        <div
          data-np-handle-id={p.elementId}
          data-np-handle-disabled={p.disabled || undefined}
          style={{
            display: editorUi.movingElementId ? "none" : undefined,
            "--bg": `url(${gridImage})`,
            cursor: p.disabled
              ? undefined
              : (
                  {
                    selecting: "pointer",
                    deleting: "no-drop",
                    moving: "grab",
                  } as Record<string, string>
                )[editorUi.viewport.tool],
          }}
          class={clsx(
            classes["handle"],
            editorUi.selectedElementId !== p.elementId && "selectable",
            hovered() && classes["handle--hover"],
            !p.disabled &&
              editorUi.viewport.tool === "moving" &&
              moveHandleClass(),
          )}
        />
        <Show when={hovered()}>
          <Suspense>
            <Selection
              elementRef={p.elementRef}
              showLabel={p.elementId !== ROOT_ELEMENT_ID}
            />
          </Suspense>
        </Show>
      </Show>
    </>
  );
};

export default Handles;
