import { useEffect, useState } from 'react';

export interface VisualViewportInsets {
  /** The visual viewport's current height (shrinks when the on-screen
   *  keyboard opens). Falls back to `window.innerHeight` when
   *  `visualViewport` isn't supported. */
  height: number;
  /** Extra inset a `position: fixed`, bottom-anchored element should add to
   *  its own `bottom` offset to stay clear of the on-screen keyboard --
   *  `window.innerHeight` minus the visual viewport's bottom edge (its
   *  height + offsetTop). Zero whenever no keyboard is open, or
   *  `visualViewport` isn't supported (a safe no-op fallback). */
  keyboardInset: number;
}

const ZERO_INSETS: VisualViewportInsets = { height: 0, keyboardInset: 0 };

function computeInsets(): VisualViewportInsets {
  if (typeof window === 'undefined') return ZERO_INSETS;
  const vv = window.visualViewport;
  if (!vv) return { height: window.innerHeight, keyboardInset: 0 };
  const keyboardInset = Math.max(0, window.innerHeight - (vv.height + vv.offsetTop));
  return { height: vv.height, keyboardInset };
}

/**
 * Tracks `window.visualViewport`'s height/offset (item 5, Phase B) so
 * `BottomSheet` can stay clear of the on-screen keyboard. `position: fixed`
 * elements are positioned against the LAYOUT viewport, which does NOT shrink
 * when a mobile keyboard opens -- only the visual viewport does -- so a
 * bottom-anchored sheet's inputs can otherwise end up hidden underneath the
 * keyboard with no visual indication anything is wrong.
 *
 * Guards for browsers without `visualViewport` (older WebViews): falls back
 * to `{ height: window.innerHeight, keyboardInset: 0 }`, i.e. a no-op, so
 * the sheet just keeps its existing (keyboard-unaware) sizing there.
 */
export function useVisualViewportInsets(): VisualViewportInsets {
  const [insets, setInsets] = useState<VisualViewportInsets>(computeInsets);

  useEffect(() => {
    if (typeof window === 'undefined' || !window.visualViewport) return;
    const vv = window.visualViewport;
    const handleChange = () => setInsets(computeInsets());
    handleChange();
    vv.addEventListener('resize', handleChange);
    vv.addEventListener('scroll', handleChange);
    return () => {
      vv.removeEventListener('resize', handleChange);
      vv.removeEventListener('scroll', handleChange);
    };
  }, []);

  return insets;
}
