import * as React from "react";
import { cn } from "@/lib/utils";

interface HorizontalScrollListProps {
	children: React.ReactNode;
	className?: string;
	scrollStep?: number;
	onScrollableChange?: (
		canScrollLeft: boolean,
		canScrollRight: boolean,
	) => void;
}

export interface HorizontalScrollListRef {
	scrollLeft: () => void;
	scrollRight: () => void;
}

export const HorizontalScrollList = React.forwardRef<
	HorizontalScrollListRef,
	HorizontalScrollListProps
>(({ children, className, scrollStep = 200, onScrollableChange }, ref) => {
	const scrollRef = React.useRef<HTMLDivElement>(null);

	const checkScrollable = React.useCallback(() => {
		if (!scrollRef.current || !onScrollableChange) return;

		const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current;
		const canScrollLeft = scrollLeft > 0;
		const canScrollRight = scrollLeft + clientWidth < scrollWidth;

		onScrollableChange(canScrollLeft, canScrollRight);
	}, [onScrollableChange]);

	const scrollLeft = React.useCallback(() => {
		if (!scrollRef.current) return;
		scrollRef.current.scrollBy({ left: -scrollStep, behavior: "smooth" });
	}, [scrollStep]);

	const scrollRight = React.useCallback(() => {
		if (!scrollRef.current) return;
		scrollRef.current.scrollBy({ left: scrollStep, behavior: "smooth" });
	}, [scrollStep]);

	React.useEffect(() => {
		checkScrollable();
	}, [checkScrollable]);

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

		const handleScroll = () => {
			checkScrollable();
		};

		const handleResize = () => {
			checkScrollable();
		};

		element.addEventListener("scroll", handleScroll);
		window.addEventListener("resize", handleResize);

		return () => {
			element.removeEventListener("scroll", handleScroll);
			window.removeEventListener("resize", handleResize);
		};
	}, [checkScrollable]);

	React.useImperativeHandle(
		ref,
		() => ({
			scrollLeft,
			scrollRight,
		}),
		[scrollLeft, scrollRight],
	);

	return (
		<div className={cn("w-full", className)}>
			<section
				ref={scrollRef}
				className="scrollbar-hide no-scrollbar flex gap-2 overflow-x-auto overflow-y-hidden scroll-smooth"
				aria-label="Scrollable content"
			>
				{children}
			</section>
		</div>
	);
});

HorizontalScrollList.displayName = "HorizontalScrollList";
