import { type FC, useEffect, useRef, useState } from 'react';

import {
  IconArrowBigRightLines,
  IconFile,
  IconInfoCircle,
} from '@material-hu/icons/tabler';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';
import { type FileAsset } from '@material-hu/types/attachments';

import { Document, Page } from 'src/config/react-pdf';
import RichText from 'src/pages/dashboard/performance/components/RichText';
import { type ServiceItem } from 'src/pages/dashboard/serviceManagement/types';
import { useLokaliseTranslation } from 'src/utils/i18n';

import TypographyLinkSensitive from '../../../general/TypographyLinkSensitive';
import { usePdfCompletion } from '../contexts/PdfFormCompletionProvider';

type Props = {
  serviceItem: ServiceItem;
  pdfFileAsset: FileAsset;
};

const MIN_PAGE_WIDTH = 80;
const CONTAINER_PADDING = 36;

const ExpandableInfoSidebar: FC<Props> = ({ serviceItem, pdfFileAsset }) => {
  const { t } = useLokaliseTranslation('service_management');
  const { currentPage, totalPages, scrollToPage } = usePdfCompletion();

  // Dynamically fit pdf page thumbnails to the available width of the sidebar list
  const thumbsContainerRef = useRef<HTMLDivElement | null>(null);
  const [thumbWidth, setThumbWidth] = useState<number>(150);
  const [expandedTab, setExpandedTab] = useState<string | null>(null);

  const handleToggleTab = (tab: string | null) => {
    setExpandedTab(tab);
  };

  // biome-ignore lint/correctness/useExhaustiveDependencies: re-run when the tab toggles to re-observe the newly mounted thumbs container
  useEffect(() => {
    const el = thumbsContainerRef.current;
    if (!el) return;

    let animationFrame = 0;
    const measure = () => {
      const available = Math.max(
        MIN_PAGE_WIDTH,
        Math.floor(el.clientWidth - CONTAINER_PADDING),
      );
      setThumbWidth(available);
    };

    const observer = new ResizeObserver(() => {
      cancelAnimationFrame(animationFrame);
      animationFrame = requestAnimationFrame(measure);
    });
    observer.observe(el);
    measure();

    return () => {
      observer.disconnect();
      cancelAnimationFrame(animationFrame);
    };
  }, [expandedTab]);

  return (
    <Stack sx={{ flexDirection: 'row' }}>
      {expandedTab === 'info' && (
        <Stack
          sx={{
            width: ['200px', '240px', '288px'],
            backgroundColor: ({ palette }) =>
              palette.new.background.layout.tertiary,
          }}
        >
          <Stack
            sx={{
              width: 1,
              cursor: 'pointer',
              flexDirection: 'row',
              alignItems: 'center',
              p: 2,
              gap: 1,
            }}
          >
            <IconButton
              variant="secondary"
              onClick={() => handleToggleTab(null)}
            >
              <IconArrowBigRightLines size={24} />
            </IconButton>
            <Typography
              variant="globalS"
              fontWeight="fontWeightSemiBold"
              sx={{ color: ({ palette }) => palette.new.text.neutral.default }}
            >
              {t('description')}
            </Typography>
          </Stack>
          <Stack sx={{ px: 3, py: 2, gap: 1 }}>
            {serviceItem.description && (
              <TypographyLinkSensitive
                variant="globalXS"
                sx={{
                  color: ({ palette }) => palette.new.text.neutral.default,
                  display: 'block',
                  wordBreak: 'break-word',
                  overflowWrap: 'break-word',
                }}
              >
                {serviceItem.description}
              </TypographyLinkSensitive>
            )}
            {serviceItem.richDescription && (
              <RichText
                sx={{
                  display: 'block',
                  wordBreak: 'break-word',
                  overflowWrap: 'break-word',
                }}
                openLinksInNewTab
                text={serviceItem.richDescription}
              />
            )}
          </Stack>
        </Stack>
      )}
      {expandedTab === 'file' && (
        <Stack
          sx={{
            width: ['200px', '240px', '288px'],
            height: 1,
            minHeight: 0,
            backgroundColor: ({ palette }) =>
              palette.new.background.layout.tertiary,
          }}
        >
          <Stack
            sx={{
              width: 1,
              cursor: 'pointer',
              flexDirection: 'row',
              alignItems: 'center',
              p: 2,
              gap: 1,
            }}
          >
            <IconButton
              variant="secondary"
              onClick={() => handleToggleTab(null)}
            >
              <IconArrowBigRightLines size={24} />
            </IconButton>
            <Typography
              variant="globalS"
              fontWeight="fontWeightSemiBold"
              sx={{ color: ({ palette }) => palette.new.text.neutral.default }}
            >
              {t('pages')}
            </Typography>
          </Stack>

          <Stack
            sx={{ px: 2, pb: 2, overflowY: 'auto', minHeight: 0 }}
            ref={thumbsContainerRef}
          >
            {pdfFileAsset?.url && totalPages > 0 && (
              <Document
                file={pdfFileAsset.url}
                loading=""
                error=""
              >
                <Stack sx={{ gap: 2 }}>
                  {Array.from({ length: totalPages }, (_, i) => {
                    const pageNumber = i + 1;
                    return (
                      <Stack
                        key={pageNumber}
                        onClick={() => scrollToPage(pageNumber, 'smooth')}
                        sx={{
                          borderRadius: 1,
                          border: ({ palette }) =>
                            `1px solid ${pageNumber === currentPage ? palette.primary?.main : 'transparent'}`,
                          cursor: 'pointer',
                          overflowX: 'auto',
                          alignItems: 'center',
                          backgroundColor: ({ palette }) =>
                            palette.new.background.layout.default,
                        }}
                      >
                        <Page
                          pageNumber={pageNumber}
                          width={thumbWidth}
                          renderAnnotationLayer={false}
                          renderTextLayer={false}
                          loading=""
                        />
                      </Stack>
                    );
                  })}
                </Stack>
              </Document>
            )}
          </Stack>
        </Stack>
      )}
      <Stack
        sx={{
          alignItems: 'center',
          gap: 2,
          p: 2,
          borderLeft: ({ palette }) =>
            `1px solid ${palette.new.border.neutral.default}`,
          backgroundColor: ({ palette }) =>
            palette.new.background.layout.tertiary,
        }}
      >
        <IconButton
          onClick={() => setExpandedTab(expandedTab === 'info' ? null : 'info')}
        >
          <IconInfoCircle size={24} />
        </IconButton>
        <IconButton
          onClick={() => setExpandedTab(expandedTab === 'file' ? null : 'file')}
        >
          <IconFile size={24} />
        </IconButton>
      </Stack>
    </Stack>
  );
};

export default ExpandableInfoSidebar;
