import { useEffect, useRef, useState } from "react";
import type { ReactNode } from "react";
import styles from "./HScrollTable.module.css";

interface HScrollTableProps {
  minWidth: number;
  maxHeight?: number | string;
  children: ReactNode;
}

/**
 * Adds synced horizontal scrollbars above and below wide content.
 */
export function HScrollTable({
  minWidth,
  maxHeight,
  children,
}: HScrollTableProps) {
  const topRef = useRef<HTMLDivElement>(null);
  const bodyRef = useRef<HTMLDivElement>(null);
  const [contentWidth, setContentWidth] = useState(minWidth);
  const syncing = useRef<"top" | "body" | null>(null);

  useEffect(() => {
    const el = bodyRef.current;
    if (!el) return;
    const measure = () => setContentWidth(el.scrollWidth);
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(el);
    return () => ro.disconnect();
  }, []);

  const handleScroll = (source: "top" | "body") => () => {
    if (syncing.current && syncing.current !== source) return;
    const from = source === "top" ? topRef.current : bodyRef.current;
    const to = source === "top" ? bodyRef.current : topRef.current;
    if (!from || !to) return;
    syncing.current = source;
    to.scrollLeft = from.scrollLeft;
    requestAnimationFrame(() => {
      syncing.current = null;
    });
  };

  return (
    <>
      <div
        ref={topRef}
        className={styles.topScroll}
        onScroll={handleScroll("top")}
      >
        <div style={{ width: contentWidth, height: 1 }} />
      </div>
      <div
        ref={bodyRef}
        className={styles.bodyScroll}
        onScroll={handleScroll("body")}
        style={maxHeight !== undefined ? { maxHeight } : undefined}
      >
        {children}
      </div>
    </>
  );
}
