import React, {CSSProperties, useCallback, useEffect, useImperativeHandle, useRef} from "react";
import {useInViewport, useScroll} from "ahooks";
import { LoadingOutlined } from '@ant-design/icons';
import {Spin} from "antd";

export type InfiniteScrollerRef = {
	scrollToPosition: (top: number) => void
};
export type InfiniteScrollerProps = {
	children?: React.ReactNode;
	className?: string;
	rootClassName?: string;
	style?: CSSProperties;
	loadingPlaceholder?: React.ReactNode;
	onCallback?: (page: number, prevPage) => void;
	onScroll?: (top: number) => void;
	empty?: React.ReactNode;
	loading?: boolean;
	pagination?: {
		page: number;
		limit: number;
		total: number;
	};
}
const InfiniteScroller = React.forwardRef<InfiniteScrollerRef, InfiniteScrollerProps>((props, ref) => {
	const {pagination} = props;
	const [inView] = useInViewport(() => document.querySelector('.data-load-control-element'))
	const scrollContainerRef = useRef<HTMLDivElement | null>(null)
	const scrollPosition = useScroll(scrollContainerRef);
	const scrollToPosition = useCallback((top: number) => {
		if (scrollContainerRef.current) {
			scrollContainerRef.current!.scrollTo({
				top,
				behavior: 'smooth'
			})
		}
	}, [scrollContainerRef])

	useImperativeHandle(ref, () => {
		return {
			scrollToPosition
		}
	})

	useEffect(() => {
		if (scrollPosition && props.onScroll) {
			props.onScroll(scrollPosition.top)
		}
	}, [scrollPosition])

	useEffect(() => {
		if (!pagination) return;
		if (inView && !props.loading && pagination.total > 0) {
			const maxPage = Math.ceil((pagination.total || 0) / pagination.limit)
			const currentPage = pagination.page
			if (maxPage > currentPage) {
				props.onCallback?.(currentPage + 1, currentPage)
			}
		}
	}, [inView])

	return (<div ref={scrollContainerRef} className={`data-list-container ${props.rootClassName}`} style={props.style}>
		<Spin wrapperClassName="data-list-load-spin" spinning={props.loading} indicator={<LoadingOutlined style={{fontSize:30}} spin />}>
		<div className={`data-list-container-inner ${props.className}`}>{props.children}</div>
			{props.loading && <div style={{minHeight:'30vh'}}></div>}
		{props?.pagination && props.pagination.total > props.pagination.limit * props.pagination.page && (props.loadingPlaceholder ||
            <div className="data-load-control-element py-10 text-center">
                <div className="loading-text">加载中...</div>
            </div>)}
		{props?.empty && !props.loading && props.pagination?.total == 0 && <div className="flex justify-center text-center pt-20">
            <div className="rounded-lg px-4 py-10">
					{props.empty}
            </div>
        </div>}
		</Spin>
	</div>);
}) //(props: InfiniteScrollerProps) =>{}
export default InfiniteScroller