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

import Icon from '../Icon';
import Drawer from '../Drawer';
import Thumbnail from '../Thumbnail';
import { Wrapper, Head, Body, IconWrapper } from '../../global/sidebarStyled'
import { ScrollStateType } from '../../constants/type';

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

import { ThumbnailsWrapper } from './styled';

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

const Thumbnails : React.FunctionComponent<Props> = ({
  isActive = false,
  close,
  currentPage,
  totalPage,
  getPdfImage,
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const [scrollIndex, setScrollIndex] = useState(currentPage);
  const [elements, setElement] = useState<React.ReactNode[]>([]);
  
  const scrollUpdate = (state: ScrollStateType) => {
    const height = 220;
    const index = Math.round((state.lastY + height) / height);
    setScrollIndex(index);
  };

  const createThumbnails = () => {
    const eleContent: React.ReactNode[] = [];
    for(let i = 1; i <= totalPage; i++) {
      const component = (
        <Thumbnail
          key={`thumbnail_${i}`}
          pageNum={i}
          getPdfImage={getPdfImage}
          renderingState={[1,2,3,4,5].includes(i) ? 'RENDERING' : 'LOADING'}
        />
      );
      eleContent.push(component);
    }
    setElement(eleContent);
  }
  
  const updateThumbnails = () => {
    const renderingIndexQueue = [scrollIndex - 1 ,scrollIndex, scrollIndex + 1, scrollIndex + 2, scrollIndex + 3];
    let index = scrollIndex - 5;
    const end = scrollIndex + 5;

    while (true) {
      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}`)!;
      scrollIntoView(ele);
    }
  }, [currentPage, isActive]);

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

export default Thumbnails;
