import {
  useCallback,
  useEffect,
  useRef,
  useState,
  type KeyboardEvent as ReactKeyboardEvent,
  type PointerEvent as ReactPointerEvent
} from "react";
import {
  WORKBENCH_LAYOUT,
  clampAgentPanelWidth,
  getAgentPanelDefaultWidth,
  getAgentPanelMaxWidth
} from "../layout/workbench-layout";

export function useAgentPanelResize(viewportWidth: number, conditionExpanded = false) {
  const panelRef = useRef<HTMLDivElement | null>(null);
  const resizeLeftRef = useRef(0);
  const cleanupRef = useRef<(() => void) | null>(null);
  const widthRef = useRef<number | null>(null);
  const [width, setWidth] = useState<number | null>(null);
  const [committedWidth, setCommittedWidth] = useState<number | null>(null);
  const [resizing, setResizing] = useState(false);

  useEffect(() => () => cleanupRef.current?.(), []);

  useEffect(() => {
    if (widthRef.current === null) {
      return;
    }

    const nextWidth = clampAgentPanelWidth(widthRef.current, viewportWidth, conditionExpanded);
    widthRef.current = nextWidth;
    setWidth(nextWidth);
    setCommittedWidth(nextWidth);
  }, [conditionExpanded, viewportWidth]);

  const resize = useCallback(
    (clientX: number) => {
      const nextWidth = clampAgentPanelWidth(
        clientX - resizeLeftRef.current,
        window.innerWidth,
        conditionExpanded
      );
      widthRef.current = nextWidth;
      setWidth(nextWidth);
    },
    [conditionExpanded]
  );

  const handlePointerDown = useCallback(
    (event: ReactPointerEvent<HTMLDivElement>) => {
      if (event.button !== 0 || !panelRef.current) return;

      event.preventDefault();
      resizeLeftRef.current = panelRef.current.getBoundingClientRect().left;
      setResizing(true);
      resize(event.clientX);

      cleanupRef.current?.();
      const handlePointerMove = (pointerEvent: PointerEvent) => {
        pointerEvent.preventDefault();
        resize(pointerEvent.clientX);
      };
      const stopResizing = () => {
        cleanupRef.current?.();
        setResizing(false);
        setCommittedWidth(widthRef.current);
      };
      const cleanup = () => {
        window.removeEventListener("pointermove", handlePointerMove);
        window.removeEventListener("pointerup", stopResizing);
        window.removeEventListener("pointercancel", stopResizing);
        cleanupRef.current = null;
      };

      cleanupRef.current = cleanup;
      window.addEventListener("pointermove", handlePointerMove);
      window.addEventListener("pointerup", stopResizing);
      window.addEventListener("pointercancel", stopResizing);
    },
    [resize]
  );

  const handleKeyDown = useCallback(
    (event: ReactKeyboardEvent<HTMLDivElement>) => {
      const currentWidth =
        panelRef.current?.getBoundingClientRect().width ?? WORKBENCH_LAYOUT.desktop.agentWidth;
      let nextWidth = currentWidth;

      if (event.key === "ArrowLeft") {
        nextWidth -= 16;
      } else if (event.key === "ArrowRight") {
        nextWidth += 16;
      } else if (event.key === "Home") {
        nextWidth = getAgentPanelDefaultWidth(window.innerWidth, conditionExpanded);
      } else if (event.key === "End") {
        nextWidth = getAgentPanelMaxWidth(window.innerWidth, conditionExpanded);
      } else {
        return;
      }

      event.preventDefault();
      const clampedWidth = clampAgentPanelWidth(nextWidth, window.innerWidth, conditionExpanded);
      widthRef.current = clampedWidth;
      setWidth(clampedWidth);
      setCommittedWidth(clampedWidth);
    },
    [conditionExpanded]
  );

  return {
    committedWidth,
    handleKeyDown,
    handlePointerDown,
    panelRef,
    resizing,
    width
  };
}
