import { useLayoutEffect, useMemo, useState } from 'react';

const DEFAULT_BOTTOM = '0.83rem';

export const getBottomOffset = (wrapperElement, inputElement, hasError) => {
  if (!wrapperElement || !inputElement) {
    return DEFAULT_BOTTOM;
  }

  if (!hasError) {
    return DEFAULT_BOTTOM;
  }

  const inputRect = inputElement.getBoundingClientRect();
  const wrapperRect = wrapperElement.getBoundingClientRect();
  const inputBottomFromWrapperTop = inputRect.bottom - wrapperRect.top;
  const distanceFromWrapperBottom = wrapperRect.height - inputBottomFromWrapperTop;

  return `${Math.max(distanceFromWrapperBottom + 4, 4)}px`;
};

export const useAiraTriggerPosition = ({
  wrapperRef,
  inputRef,
  rightOffset = '2.5rem',
  error,
}) => {
  const [bottomOffset, setBottomOffset] = useState(DEFAULT_BOTTOM);

  useLayoutEffect(() => {
    const wrapperElement = wrapperRef?.current;
    if (!wrapperElement) {
      setBottomOffset(DEFAULT_BOTTOM);
      return undefined;
    }

    const updatePosition = () => {
      const inputElement = inputRef?.current;
      const hasError = Boolean(
        error
        || wrapperElement.querySelector('.error-message')
        || wrapperElement.querySelector('.webpush-template-message-error'),
      );
      const nextOffset = getBottomOffset(wrapperElement, inputElement, hasError);
      setBottomOffset((prevOffset) => (
        prevOffset === nextOffset ? prevOffset : nextOffset
      ));
    };

    updatePosition();

    let resizeObserver = null;

    if (window.ResizeObserver) {
      resizeObserver = new window.ResizeObserver(() => {
        updatePosition();
      });
      resizeObserver.observe(wrapperElement);
      if (inputRef?.current) {
        resizeObserver.observe(inputRef.current);
      }
    }

    return () => {
      if (resizeObserver) {
        resizeObserver.disconnect();
      }
    };
  }, [wrapperRef, inputRef, error]);

  return useMemo(
    () => ({
      bottom: bottomOffset,
      right: rightOffset,
      left: 'auto',
    }),
    [bottomOffset, rightOffset],
  );
};

