import { useEffect, useState } from "react";

export interface VisualViewportState {
  width: number;
  height: number;
  keyboardInset: number;
  offsetTop: number;
  offsetLeft: number;
}

function readState(): VisualViewportState {
  if (typeof window === "undefined") {
    return { width: 0, height: 0, keyboardInset: 0, offsetTop: 0, offsetLeft: 0 };
  }
  const vv = window.visualViewport;
  if (!vv) {
    return {
      width: window.innerWidth,
      height: window.innerHeight,
      keyboardInset: 0,
      offsetTop: 0,
      offsetLeft: 0,
    };
  }
  const inset = Math.max(0, window.innerHeight - vv.height - vv.offsetTop);
  return {
    width: vv.width,
    height: vv.height,
    keyboardInset: inset,
    offsetTop: vv.offsetTop,
    offsetLeft: vv.offsetLeft,
  };
}

export function useVisualViewport(): VisualViewportState {
  const [state, setState] = useState<VisualViewportState>(() => readState());

  useEffect(() => {
    const vv = window.visualViewport;
    if (!vv) return;
    let raf = 0;
    const update = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => setState(readState()));
    };
    vv.addEventListener("resize", update);
    vv.addEventListener("scroll", update);
    window.addEventListener("orientationchange", update);
    update();
    return () => {
      cancelAnimationFrame(raf);
      vv.removeEventListener("resize", update);
      vv.removeEventListener("scroll", update);
      window.removeEventListener("orientationchange", update);
    };
  }, []);

  return state;
}
