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

import Icon from '../Icon';
import Drawer from '../Drawer';
import Thumbnail from '../Thumbnail';
import { watchScroll, scrollIntoView } from '../../helpers/utility';

import { Container, Head, IconWrapper } from '../../global/sidebarStyled';
import { ThumbnailsWrapper, Body } from './styled';

type Props = {
  isActive: boolean;
  close: () => void;
  currentPage: number;
  totalPage: number;
  getPdfImage: (page: number) => Promise<string>;
};

const Thumbnails: React.FC<Props> = ({
  isActive = false,
  close,
  currentPage,
  totalPage,
  getPdfImage,
}: Props) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const [scrollIndex, setScrollIndex] = useState(currentPage);
  const [elements, setElement] = useState<React.ReactNode[]>([]);

  const scrollUpdate = (state: ScrollStateType): void => {
    const height = 220;
    const index = Math.round((state.lastY + height) / height);

    setScrollIndex(index);
  };

  const createThumbnails = (): void => {
    const eleContent: React.ReactNode[] = [];
    for (let i = 1; i <= totalPage; i += 1) {
      const component = (
        <Thumbnail
          key={`thumbnail_${i}`}
          pageNum={i}
          getPdfImage={getPdfImage}
          renderingState={_.range(1, 6).includes(i) ? 'RENDERING' : 'LOADING'}
        />
      );
      eleContent.push(component);
    }
    setElement(eleContent);
  };

  const updateThumbnails = (): void => {
    const renderingIndexQueue = _.range(scrollIndex - 2, scrollIndex + 4);
    let index = scrollIndex - 6;
    const end = scrollIndex + 6;

    while (scrollIndex) {
      if (elements[index]) {
        const pageNum = index + 1;

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

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

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

  useEffect(() => {
    if (containerRef.current) {
      watchScroll(containerRef.current, scrollUpdate);
    }
  }, [containerRef]);

  useEffect(() => {
    if (isActive && !elements.length) {
      createThumbnails();
    }
  }, [isActive]);

  useEffect(() => {
    updateThumbnails();
  }, [scrollIndex]);

  useEffect(() => {
    if (isActive && elements.length) {
      const ele: HTMLElement = document.getElementById(
        `thumbnail_${currentPage}`,
      ) as HTMLElement;
      scrollIntoView(ele);
    }
  }, [currentPage, isActive]);

  return (
    <Drawer anchor="right" open={isActive}>
      <Container>
        <Head>
          <IconWrapper>
            <Icon glyph="right-back" onClick={close} />
          </IconWrapper>
        </Head>
        <Body ref={containerRef}>
          <ThumbnailsWrapper>{elements}</ThumbnailsWrapper>
        </Body>
      </Container>
    </Drawer>
  );
};

export default Thumbnails;
