import { cn } from '@/lib/utils';
import { useEffect, useRef, useState, type ReactNode } from 'react';

/**
 * Horizontal scroller whose scrollbar sits ABOVE the content instead of below it,
 * so a tall board (the onboarding kanban) can be panned left/right without first
 * scrolling to the bottom of the page to reach the native bar.
 *
 * Implemented as a proxy bar kept in sync with the real scroller, NOT with the
 * usual `transform: rotateX(180deg)` double-flip: a transformed ancestor becomes
 * the containing block for fixed/absolute descendants, which would quietly move
 * every dropdown and tooltip rendered inside the cards.
 *
 * The real scroller keeps its scrolling behaviour and only hides its own bar, so
 * wheel, trackpad, touch and keyboard panning are untouched.
 */
export const HorizontalScroller = ({ className, children }: { className?: string; children: ReactNode }) => {
    const scrollRef = useRef<HTMLDivElement>(null);
    const proxyRef = useRef<HTMLDivElement>(null);
    /** Guards the two-way sync: assigning scrollLeft fires the other's scroll event. */
    const syncing = useRef(false);
    const [contentWidth, setContentWidth] = useState(0);
    const [overflowing, setOverflowing] = useState(false);

    useEffect(() => {
        const el = scrollRef.current;
        if (!el) return;

        const measure = () => {
            setContentWidth(el.scrollWidth);
            // +1 absorbs sub-pixel rounding, which would otherwise show an inert bar.
            setOverflowing(el.scrollWidth > el.clientWidth + 1);
        };

        measure();
        const observer = new ResizeObserver(measure);
        observer.observe(el);
        Array.from(el.children).forEach((child) => observer.observe(child));
        return () => observer.disconnect();
    }, [children]);

    const mirror = (from: HTMLDivElement | null, to: HTMLDivElement | null) => {
        if (!from || !to || syncing.current) return;
        syncing.current = true;
        to.scrollLeft = from.scrollLeft;
        requestAnimationFrame(() => {
            syncing.current = false;
        });
    };

    return (
        <>
            <div
                ref={proxyRef}
                onScroll={() => mirror(proxyRef.current, scrollRef.current)}
                className={cn('mb-2 overflow-x-auto', overflowing ? 'hidden sm:block' : 'hidden')}
                aria-hidden
            >
                <div style={{ width: contentWidth, height: 1 }} />
            </div>
            <div
                ref={scrollRef}
                onScroll={() => mirror(scrollRef.current, proxyRef.current)}
                className={cn(className, 'sm:[scrollbar-width:none] sm:[&::-webkit-scrollbar]:hidden')}
            >
                {children}
            </div>
        </>
    );
};
