import React, { useCallback, useRef } from 'react';
import { Data } from '../../../types/data';
import { ListRow, ListRowProps } from '../ListRow/ListRow';

interface RowRendererProps<T extends Data> {
  /**
   * Custom renderer for the list row.
   * If provided, it will override the default ListRow rendering.
   * In case it returns null, the default ListRow will not be rendered.
   */
  customRowRenderer?: (props: ListRowProps<T>) => React.ReactElement | null;
  /** Props passed to the ListRow and custom renderer */
  listRowProps: ListRowProps<T>;
  /** Whether or not the item is a trigger for pagination (default: false) */
  isTrigger?: boolean;
  /**
   * A function that is getting called, when the element acts as a trigger (`isTrigger = true`) and gets into view.
   */
  onTriggered?: () => void;
}

export const ListRowRenderer = <T extends Data>({
  listRowProps,
  isTrigger = false,
  customRowRenderer,
  onTriggered,
}: RowRendererProps<T>): React.ReactElement<
  T,
  string | React.JSXElementConstructor<T>
> | null => {
  // Pagination trigger logic
  // Trigger based on: https://www.youtube.com/watch?v=NZKUirTtxcg
  const onTriggeredHandler = useCallback(() => {
    onTriggered && onTriggered();
  }, [onTriggered]);

  const observer = useRef<IntersectionObserver>();
  const elementRef = useCallback(
    (node: HTMLDivElement) => {
      if (isTrigger === false) {
        return;
      }
      if (observer.current) {
        observer.current.disconnect();
      }
      observer.current = new IntersectionObserver(([entry]) => {
        if (entry.isIntersecting) {
          onTriggeredHandler();
        }
      });

      if (node) {
        observer.current.observe(node);
      }
    },
    [isTrigger, onTriggeredHandler],
  );

  if (customRowRenderer) {
    const customElement = customRowRenderer(listRowProps);

    if (customElement) {
      return <div ref={isTrigger ? elementRef : null}>{customElement}</div>;
    }
  }

  return <ListRow {...listRowProps} ref={isTrigger ? elementRef : null} />;
};
