'use client';

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

/**
 * Detects the height of any element covering the top of the viewport.
 *
 * Strategy: uses elementFromPoint() along the top of the viewport to find
 * whatever is actually rendered there — fixed, sticky, or in-flow elements.
 * Walks up the DOM from the hit element to find the topmost covering block.
 *
 * Performance:
 * - Samples a few x-points across the viewport top (not the whole width)
 * - Throttled with requestAnimationFrame
 * - Only re-runs on resize (navbars rarely change height on scroll)
 */

const SAMPLE_POINTS = 5; // how many x positions to probe across viewport

function measureNavbarHeight(): number {
  const vv = window.visualViewport;
  const viewportWidth = vv?.width ?? document.documentElement.clientWidth;

  let maxBottom = 0;

  for (let i = 0; i < SAMPLE_POINTS; i++) {
    const x = (viewportWidth / (SAMPLE_POINTS + 1)) * (i + 1);

    // Probe just below the very top — y=1 to avoid hitting browser chrome
    const el = document.elementFromPoint(x, 1);
    if (!el || el === document.documentElement || el === document.body) continue;

    const rect = el.getBoundingClientRect();
    // Only count elements that are anchored at the very top (top ≤ 2px)
    if (rect.top <= 2 && rect.bottom > maxBottom) {
      maxBottom = rect.bottom;
    }
  }

  return maxBottom;
}

export function useNavbarHeight(): number {
  const [height, setHeight] = useState(0);
  const rafRef = useRef<number | null>(null);

  const scheduleUpdate = () => {
    if (rafRef.current !== null) return;
    rafRef.current = requestAnimationFrame(() => {
      rafRef.current = null;
      setHeight(measureNavbarHeight());
    });
  };

  useEffect(() => {
    // Initial measure after first paint
    scheduleUpdate();

    // Navbars can change height on resize (mobile keyboard, orientation)
    const vv = window.visualViewport;
    if (vv) {
      vv.addEventListener('resize', scheduleUpdate);
    } else {
      window.addEventListener('resize', scheduleUpdate, { passive: true });
    }

    // Watch for navbar being added/removed from DOM
    const mo = new MutationObserver(scheduleUpdate);
    mo.observe(document.body, { childList: true, subtree: false });

    return () => {
      if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
      if (vv) {
        vv.removeEventListener('resize', scheduleUpdate);
      } else {
        window.removeEventListener('resize', scheduleUpdate);
      }
      mo.disconnect();
    };
  }, []);

  return height;
}
