import { useEffect, useId, useRef, useState } from 'react';

const useFocusField = () => {
  const id = useId();
  const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);
  const [isFocused, setIsFocused] = useState(false);

  const handleFocus = () => {
    // Trigger render of the input, then focus it in an effect
    setIsFocused(true);
  };

  useEffect(() => {
    if (!isFocused) return;

    const raf = requestAnimationFrame(() => {
      const element =
        inputRef.current ||
        (document.getElementById(id) as
          | (HTMLInputElement | HTMLTextAreaElement)
          | null);

      if (!element) return;

      element.focus();

      // Move caret to the end
      // In some browsers setSelectionRange on type=number may throw
      try {
        const valueLength = (element as HTMLInputElement).value?.length ?? 0;
        if (
          typeof (element as HTMLInputElement).setSelectionRange === 'function'
        ) {
          (element as HTMLInputElement).setSelectionRange(
            valueLength,
            valueLength,
          );
        }
      } catch {
        // Best effort caret placement
      }

      // Ensure multiline scrolls to the bottom when caret is at the end
      if (element instanceof HTMLTextAreaElement) {
        element.scrollTop = element.scrollHeight;
      }
    });

    return () => cancelAnimationFrame(raf);
  }, [isFocused, id]);

  const removeFocus = () => {
    setIsFocused(false);
  };

  return {
    id,
    inputRef,
    isFocused,
    handleFocus,
    removeFocus,
  };
};

export default useFocusField;
