import React, { useEffect, useState, useRef } from 'react';
import _ from 'lodash';

import Viewer from '../components/Viewer';
import PdfPage from './PdfPage';
import { watchScroll } from '../helpers/utility';

import useStore from '../store';

type Props = {
  scrollToUpdate: (state: ScrollStateType) => void;
};

const PdfPages: React.FC<Props> = ({ scrollToUpdate }: Props) => {
  const [elements, setElement] = useState<React.ReactNode[]>([]);
  const containerRef = useRef<HTMLDivElement>(null);
  const [
    { totalPage, currentPage, viewport, rotation, displayMode, annotations },
  ] = useStore();

  const createPages = (): void => {
    const pagesContent: React.ReactNode[] = [];

    for (let i = 1; i <= totalPage; i += 1) {
      const key = `page-${i}`;

      const component = (
        <PdfPage
          key={key}
          index={i}
          renderingState={_.range(1, 3).includes(i) ? 'RENDERING' : 'LOADING'}
        />
      );
      pagesContent.push(component);
    }

    setElement(pagesContent);
  };

  const updatePages = (): void => {
    const renderingIndexQueue = _.range(currentPage - 1, currentPage + 2);
    let index = currentPage - 3;
    const end = currentPage + 3;

    while (currentPage) {
      if (elements[index]) {
        const pageNum = index + 1;
        const key = `page-${pageNum}`;

        elements[index] = (
          <PdfPage
            key={key}
            index={pageNum}
            renderingState={
              renderingIndexQueue.includes(pageNum) ? 'RENDERING' : 'LOADING'
            }
          />
        );
      }

      index += 1;
      if (index >= end) break;
    }

    if (elements.length) {
      setElement([...elements]);
    }
  };

  useEffect(() => {
    createPages();
    watchScroll(containerRef.current, scrollToUpdate);
  }, []);

  useEffect(() => {
    updatePages();
  }, [currentPage, viewport, rotation, annotations]);

  return (
    <Viewer
      ref={containerRef}
      viewport={viewport}
      rotation={rotation}
      displayMode={displayMode}
    >
      {elements}
    </Viewer>
  );
};

export default PdfPages;
