import {Validator, Requireable, PureComponent} from 'react';

/**
 * Specifies the number of miliseconds during which to disable pointer events while a scroll is in progress.
 * This improves performance and makes scrolling smoother.
 */
export const IS_SCROLLING_TIMEOUT = 150;

export type WindowScrollerChildProps = {
  height: number;
  width: number;
  isScrolling: boolean;
  scrollTop: number;
  scrollLeft: number;
  onChildScroll: (params: {scrollTop: number}) => void;
  registerChild: (element?: React.ReactNode) => void;
};

export type WindowScrollerProps = {
  /**
   * Function responsible for rendering children.
   * This function should implement the following signature:
   * ({ height, isScrolling, scrollLeft, scrollTop, width, onChildScroll }) => PropTypes.element
   */
  children: (params: WindowScrollerChildProps) => React.ReactNode;

  /** Callback to be invoked on-resize: ({ height, width }) */
  onResize?: ((params: {height: number; width: number}) => void) | undefined;

  /** Callback to be invoked on-scroll: ({ scrollLeft, scrollTop }) */
  onScroll?:
    | ((params: {scrollLeft: number; scrollTop: number}) => void)
    | undefined;

  /** Element to attach scroll event listeners. Defaults to window. */
  scrollElement?: typeof window | Element | undefined;
  /**
   * Wait this amount of time after the last scroll event before resetting child `pointer-events`.
   */
  scrollingResetTimeInterval?: number | undefined;

  /** Height used for server-side rendering */
  serverHeight?: number | undefined;

  /** Width used for server-side rendering */
  serverWidth?: number | undefined;
  /**
   * PLEASE NOTE
   * The [key: string]: any; line is here on purpose
   * This is due to the need of force re-render of PureComponent
   * Check the following link if you want to know more
   * https://github.com/bvaughn/react-virtualized#pass-thru-props
   */
  [key: string]: any;
};

export type WindowScrollerState = {
  height: number;
  width: number;
  isScrolling: boolean;
  scrollLeft: number;
  scrollTop: number;
};

export class WindowScroller extends PureComponent<
  WindowScrollerProps,
  WindowScrollerState
> {
  static defaultProps: {
    onResize: () => void;
    onScroll: () => void;
    scrollingResetTimeInterval: typeof IS_SCROLLING_TIMEOUT;
    scrollElement: Window | undefined;
    serverHeight: 0;
    serverWidth: 0;
  };

  updatePosition(scrollElement?: HTMLElement): void;
}

export default WindowScroller;
