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

import Spinner from '@design-system/ProgressIndicators/Spinner';
import { useTheme } from '@mui/material';
import Stack from '@mui/material/Stack';
import { Document } from '@src/config/react-pdf';
import useDimensions from '@src/hooks/useDimensions';
import useResizeObserver from '@src/hooks/useResizeObserver';
import useScroll from '@src/hooks/useScroll';
import { isScrolledToEnd } from '@utils/elements';
import times from 'lodash/times';

import { usePdfVisualizer } from '../../context';
import PdfPage from '../PdfPage';

import { type ViewerAreaProps } from './types';

const CONTAINER_PADDING = 24;

const ViewerArea = ({ sx }: ViewerAreaProps) => {
  const theme = useTheme();
  const { t } = useTranslation('material_hu_only');
  const {
    file,
    totalPages,
    baseWidth,
    setTotalPages,
    setPageWidth,
    registerScrollContainer,
    onFinishRead,
  } = usePdfVisualizer();

  const containerRef = useRef<HTMLDivElement | null>(null);
  const { dimensions } = useDimensions(containerRef.current);

  // Calculate page width based on container size and baseWidth
  useEffect(() => {
    const availableWidth = dimensions.width - CONTAINER_PADDING * 2;
    if (availableWidth <= 0) return;

    const shouldAutoFit = availableWidth < baseWidth;
    const calculatedWidth = shouldAutoFit ? availableWidth : baseWidth;

    setPageWidth(calculatedWidth);
  }, [dimensions.width, baseWidth, setPageWidth]);

  const setContainerRef = useCallback(
    (node: HTMLDivElement | null) => {
      containerRef.current = node;
      registerScrollContainer(node);
    },
    [registerScrollContainer],
  );

  const checkFinishedReading = useCallback(
    (container: HTMLElement | null) => {
      if (isScrolledToEnd(container) && onFinishRead) onFinishRead();
    },
    [onFinishRead],
  );

  useScroll(containerRef.current, checkFinishedReading);

  useResizeObserver(containerRef.current, (entries: ResizeObserverEntry[]) => {
    for (const entry of entries) {
      const element = entry.target as HTMLElement;
      checkFinishedReading(element);
    }
  });

  const handleLoadSuccess = useCallback(
    ({ numPages }: { numPages: number }) => setTotalPages(numPages),
    [setTotalPages],
  );

  return (
    <Stack
      ref={setContainerRef}
      sx={{
        flex: 1,
        overflow: 'auto',
        backgroundColor: theme.palette.new.background.layout.default,
        py: 3,
        ...sx,
        margin: '0 auto',
      }}
    >
      <Stack
        sx={{
          width: 'fit-content',
          minWidth: '100%',
          alignItems: 'center',
        }}
      >
        <Document
          file={file}
          onLoadSuccess={handleLoadSuccess}
          loading={
            <Stack
              sx={{
                height: '100%',
                alignItems: 'center',
                justifyContent: 'center',
              }}
            >
              <Spinner />
            </Stack>
          }
          error={
            <Stack
              sx={{
                height: '100%',
                alignItems: 'center',
                justifyContent: 'center',
                color: theme.palette.error.main,
              }}
            >
              {t('pdf_visualizer.error_loading_pdf')}
            </Stack>
          }
        >
          {times(totalPages, index => (
            <PdfPage
              key={`pdf-page-${index + 1}`}
              pageNumber={index + 1}
            />
          ))}
        </Document>
      </Stack>
    </Stack>
  );
};

export default ViewerArea;
