import { useEffect, useRef, useState } from "react";
import pointerSvg from "@/assets/pointer.min.svg";
import { useLazyEyes } from "@/hooks/useLazyEyes";

/**
 * Floating pointer that tracks the CodeMirror cursor vertically,
 * pinned to the left edge of the editor. Positions relative to
 * containerRef (for floating windows).
 */
export default function EditorPointer({ containerRef, focused = true }: { containerRef?: React.RefObject<HTMLElement | null>; focused?: boolean }) {
  const [y, setY] = useState<number | null>(null);
  const [editorLeft, setEditorLeft] = useState<number | null>(null);
  const targetRef = useRef(0);
  const currentRef = useRef(0);
  const rafRef = useRef(0);
  const activeRef = useRef(false);
  const [clickKey, setClickKey] = useState(0);
  const clickTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);
  const cmRef = useRef<Element | null>(null);

  // Eye anchor must be in viewport coords (useLazyEyes compares against e.clientX/Y)
  const eyeAnchorRef = useRef<{ x: number; y: number } | null>(null);
  const eyeOffset = useLazyEyes({ anchorRef: eyeAnchorRef });

  useEffect(() => {
    const ease = 0.09;

    const getContainerRect = () =>
      containerRef?.current?.getBoundingClientRect() ?? { left: 0, top: 0 };

    const updateLeft = () => {
      if (!cmRef.current || !containerRef?.current) return;
      const cmLeft = cmRef.current.getBoundingClientRect().left;
      const containerLeft = containerRef.current.getBoundingClientRect().left;
      setEditorLeft(cmLeft - containerLeft);
    };

    const onEditorClick = () => {
      clearTimeout(clickTimerRef.current);
      setClickKey((k) => k + 1);
      clickTimerRef.current = setTimeout(() => setClickKey(0), 200);
    };

    const onCursorMove = (e: Event) => {
      const { top } = (e as CustomEvent).detail;

      // Find editor container lazily, scoped to our window
      if (!cmRef.current) {
        const scope = containerRef?.current ?? document;
        const cm = scope.querySelector(".cm-editor");
        if (cm) {
          cmRef.current = cm;
          cm.addEventListener("mousedown", onEditorClick);
          ro.observe(cm);
        }
      }

      // Convert viewport top to container-relative top
      const containerTop = getContainerRect().top;
      targetRef.current = top - containerTop;
      updateLeft();

      if (!activeRef.current) {
        currentRef.current = targetRef.current;
        setY(targetRef.current);
        activeRef.current = true;
      }
    };

    const tick = () => {
      if (activeRef.current) {
        const diff = targetRef.current - currentRef.current;
        if (Math.abs(diff) < 0.5) {
          currentRef.current = targetRef.current;
        } else {
          currentRef.current += diff * ease;
        }
        setY(currentRef.current);

        // Eye anchor in viewport coords for useLazyEyes
        const cmLeft = cmRef.current?.getBoundingClientRect().left ?? 0;
        const containerTop = getContainerRect().top;
        eyeAnchorRef.current = { x: cmLeft - 100, y: containerTop + currentRef.current };
      }
      rafRef.current = requestAnimationFrame(tick);
    };

    window.addEventListener("cm-cursor-move", onCursorMove);
    rafRef.current = requestAnimationFrame(tick);

    // Keep left position updated on resize
    const ro = new ResizeObserver(() => updateLeft());
    const scope = containerRef?.current ?? document;
    const existingCm = scope.querySelector(".cm-editor");
    if (existingCm) {
      cmRef.current = existingCm;
      ro.observe(existingCm);
    }
    window.addEventListener("resize", updateLeft);

    return () => {
      window.removeEventListener("cm-cursor-move", onCursorMove);
      window.removeEventListener("resize", updateLeft);
      cmRef.current?.removeEventListener("mousedown", onEditorClick);
      cancelAnimationFrame(rafRef.current);
      ro.disconnect();
    };
  }, [containerRef]);

  if (!focused || y === null || editorLeft === null) return null;

  return (
    <div
      className={`editor-pointer${clickKey ? " editor-pointer-click" : ""}`}
      key={clickKey}
      style={{ top: y, left: editorLeft }}
    >
      <div
        className="editor-pointer-img"
        style={{
          WebkitMaskImage: `url(${pointerSvg})`,
          maskImage: `url(${pointerSvg})`,
        }}
      />
      <div className="editor-pointer-eye" style={{ top: 33, left: 134 }}>
        <div
          className="editor-pointer-iris"
          style={{ transform: `translate(${eyeOffset.x}px, ${eyeOffset.y}px)` }}
        />
      </div>
      <div className="editor-pointer-eye" style={{ top: 29, left: 144 }}>
        <div
          className="editor-pointer-iris"
          style={{ transform: `translate(${eyeOffset.x}px, ${eyeOffset.y}px)` }}
        />
      </div>
    </div>
  );
}
