import React, { useRef, useEffect, useCallback } from 'react';
import PropTypes from 'prop-types';
import { Container } from '../container/Container';
import { usePageContext } from './Page';

const propTypes = {
  children: PropTypes.node,
  tag: PropTypes.elementType,
};

const defaultProps = {
  children: '',
  tag: 'div',
};

export const PageContent = ({ children, tag: Tag }) => {
  const {
    size,
    gutterHorizontal,
    isContentScrolled,
    setIsContentScrolled,
    rangeAnimationShouldNotStart,
    shouldNotAnimateTopBar,
    setShouldNotAnimateTopBar,
  } = usePageContext();

  const scrollRef = useRef();
  const isContentScrolledRef = useRef();
  isContentScrolledRef.current = isContentScrolled;

  const handleScroll = useCallback((e) => {
    const { scrollTop } = e.srcElement || {};

    const isScrolled = (scrollTop && scrollTop > 0) || false;

    // Do not trigger shriking of the page top bar if the scrollTop
    // is too little, otherwise we get stuck in a loop
    if (shouldNotAnimateTopBar && isScrolled) {
      return;
    }

    if (isScrolled !== isContentScrolledRef.current) {
      setIsContentScrolled(isScrolled);
    }
  }, [rangeAnimationShouldNotStart, setIsContentScrolled, shouldNotAnimateTopBar]);

  useEffect(() => {
    if (!scrollRef.current || !rangeAnimationShouldNotStart) {
      return () => {};
    }

    const { scrollHeight, clientHeight } = scrollRef.current;

    const noScroll = scrollHeight - clientHeight > 0;
    const notEnoughScroll = scrollHeight - clientHeight <= rangeAnimationShouldNotStart;
    const isContentNotScrollableEnough = noScroll && notEnoughScroll;

    if (isContentNotScrollableEnough) {
      setShouldNotAnimateTopBar(true);
    }

    scrollRef.current.addEventListener('scroll', handleScroll);

    return () => {
      scrollRef.current.removeEventListener('scroll', handleScroll);
    };
  }, [rangeAnimationShouldNotStart, shouldNotAnimateTopBar, children]);

  return (
    <Tag className="sui-l-app-layout__page">
      <div className="sui-l-app-layout__page-scroll" ref={scrollRef}>
        <Container size={size} gutterHorizontal={gutterHorizontal}>
          {children}
        </Container>
      </div>
    </Tag>
  );
};

PageContent.propTypes = propTypes;
PageContent.defaultProps = defaultProps;
