interface Bounds {
  top: number;
  left: number;
  width: number;
  height: number;
}

export function getOffsetRect(el: HTMLElement | SVGElement | Text | null): Bounds {
  const isElement = el instanceof HTMLElement || el instanceof SVGElement;

  if (typeof window === 'undefined' || !isElement) {
    return {
      top: 0,
      left: 0,
      width: 0,
      height: 0,
    };
  }

  const box = el.getBoundingClientRect();
  const body = document.body;
  const doc = document.documentElement;
  const scrollTop = window.pageYOffset || doc.scrollTop || body.scrollTop;
  const scrollLeft = window.pageXOffset || doc.scrollLeft || body.scrollLeft;
  const clientTop = doc.clientTop || body.clientTop || 0;
  const clientLeft = doc.clientLeft || body.clientLeft || 0;

  return {
    top: Math.round(box.top + scrollTop - clientTop),
    left: Math.round(box.left + scrollLeft - clientLeft),
    width: Math.round(box.width),
    height: Math.round(box.height),
  };
}
