import React, { useEffect, useState, useRef, useCallback } from 'react';
import { useTranslation } from 'react-i18next';

import Typography from '../Typography';
import Item from '../AnnotationItem';

import { watchScroll } from '../../helpers/utility';
import { getAnnotationText } from '../../helpers/annotation';

import { Body } from '../../global/sidebarStyled';

type Props = {
  isActive?: boolean;
  annotations: AnnotationType[];
  viewport: ViewportType;
  scale: number;
  pdf: any;
};

const AnnotationList: React.FC<Props> = ({
  isActive = false,
  annotations,
  viewport,
  scale,
  pdf,
}: Props) => {
  let observer: any = null;
  const { t } = useTranslation('sidebar');
  const [renderQueue, setQueue] = useState<AnnotationType[]>([]);
  const containerRef = useRef<HTMLDivElement>(null);
  const innerRef = useRef<HTMLDivElement>(null);

  const getText = async (
    page: number,
    position: PositionType[]
  ): Promise<any> => {
    const text = await getAnnotationText({
      pdf,
      viewport,
      scale,
      page,
      coords: position,
    });

    return text;
  };

  const scrollUpdate = useCallback(
    (state: ScrollStateType): void => {
      const innerHeight = innerRef.current?.offsetHeight || 0;
      const wrapperHeight = containerRef.current?.offsetHeight || 0;

      if (
        wrapperHeight + state.lastY >= innerHeight &&
        renderQueue.length !== annotations.length
      ) {
        const start = renderQueue.length;
        const end = renderQueue.length + 15;
        const newQueue = [...renderQueue, ...annotations.slice(start, end)];
        setQueue(newQueue);
      }
    },
    [renderQueue, annotations]
  );

  useEffect(() => {
    observer = watchScroll(containerRef.current, scrollUpdate);

    return (): void => {
      if (observer) {
        observer.subscriber.unsubscribe();
      }
    };
  }, [containerRef, scrollUpdate]);

  useEffect(() => {
    if (isActive) {
      setQueue(annotations.slice(0, 15));
    }
  }, [isActive, annotations]);

  return (
    <Body ref={containerRef}>
      <div ref={innerRef}>
        <Typography light align="left">
          {`${annotations.length} ${t('annotation')}`}
        </Typography>
        {isActive &&
          renderQueue.map((ele, index) => {
            const key = `annot_item_${index}`;
            const {
              obj_type,
              obj_attr: { page, bdcolor, position, transparency },
            } = ele;
            const actualPage = page + 1;
            const prevAnnot = annotations[index - 1];
            const prevPage =
              index > 0 && prevAnnot ? prevAnnot.obj_attr.page + 1 : -1;

            return (
              <Item
                key={key}
                type={obj_type}
                page={actualPage}
                bdcolor={bdcolor || ''}
                transparency={transparency || 0}
                getText={(): Promise<any> =>
                  getText(actualPage, position as PositionType[])}
                showPageNum={actualPage !== prevPage}
              />
            );
          })}
      </div>
    </Body>
  );
};

export default AnnotationList;
