import { useMemo, useRef, useState } from 'react';
import { FormProvider } from 'react-hook-form';
import { useParams } from 'react-router-dom';

import { useDebounce } from '@material-hu/hooks/useDebounce';
import { useHuPagination } from '@material-hu/hooks/useHuPagination';
import Paper from '@material-hu/mui/Paper';
import Stack from '@material-hu/mui/Stack';

import HuTable from '@material-hu/components/design-system/Table';
import HuTableBody from '@material-hu/components/design-system/Table/components/TableBody';
import HuTableContainer from '@material-hu/components/design-system/Table/components/TableContainer';
import HuTableHead from '@material-hu/components/design-system/Table/components/TableHead';
import HuTableLoader from '@material-hu/components/design-system/Table/components/TableLoader';
import HuTableRow from '@material-hu/components/design-system/Table/components/TableRow';

import { logEvent } from 'src/config/amplitude';
import { useAuth } from 'src/contexts/JWTContext';
import FileRow from 'src/pages/dashboard/files/components/FileRow';
import { EventName } from 'src/types/amplitude';
import { FileTypes } from 'src/types/attachments';
import { type File } from 'src/types/files';
import { filesTableHeader } from 'src/utils/files';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { flatPages } from 'src/utils/pagination';

import FilePreview from 'src/components/attachment/FilePreview';

import { useInfiniteFiles } from '../hooks/useInfiniteFiles';

import { EmptyState } from './EmptyState';
import FileTableSkeleton from './skeleton/FileTableSkeleton';

const FilesTable = () => {
  const { id } = useParams();
  const pageRef = useRef<HTMLDivElement>(null);
  const currentFolderId = id ? Number(id) : undefined;
  const { t } = useLokaliseTranslation('files');
  const [openPreview, setOpenPreview] = useState(false);
  const [index, setIndex] = useState(0);
  const { instance } = useAuth();
  const disabledDownload = instance?.hideFileDownload;

  const columns = filesTableHeader(t);
  const columnsCount = columns.length;

  const { HuTableSortingHeader, Search, params, form } = useHuPagination({
    defaultOrderBy: 'FILE_NAME',
  });

  const { order, orderBy, pagination, search } = params;
  const debouncedSearch = useDebounce(search, 500);

  const paramsDebounced = {
    order,
    orderBy,
    pagination,
    query: debouncedSearch,
  };

  const { data, isLoading, fetchNextPage, hasNextPage } = useInfiniteFiles(
    paramsDebounced,
    currentFolderId,
  );

  const files = flatPages(data);

  const totalFiles = useMemo(() => data?.pages[0]?.data.count ?? 0, [data]);

  const handleOnClickFile = (file: File, fileIndex: number) => {
    if (file.type === FileTypes.FILE) {
      logEvent(EventName.FILE_VIEW, {
        fileId: file.id,
        folderId: file.parentId,
      });
      setOpenPreview(true);
      setIndex(fileIndex);
      return;
    }
    setIndex(0);
  };

  const handleGoBack = () => {
    setIndex(index - 1);
  };

  const handleGoForward = () => {
    setIndex(index + 1);
    if (index + 1 === files.length) {
      fetchNextPage();
    }
  };

  const handleScrollToTop = () => {
    pageRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  const isNavigationButtonGoBackDisabled = index === 0;

  const isNavigationButtonGoForwardDisabled =
    index === files.length - 1 && !hasNextPage;

  return (
    <FormProvider {...form}>
      <Stack
        sx={{ gap: 2, py: 1 }}
        ref={pageRef}
      >
        <Search />
        <HuTableContainer component={Paper}>
          <HuTable>
            <HuTableHead>
              <HuTableRow headerRow>
                {columns.map(headerElement => (
                  <HuTableSortingHeader
                    key={headerElement.id}
                    id={headerElement.id}
                  >
                    {headerElement.text}
                  </HuTableSortingHeader>
                ))}
              </HuTableRow>
            </HuTableHead>
            <HuTableBody>
              {isLoading && (
                <FileTableSkeleton
                  rows={5}
                  columns={columnsCount}
                />
              )}
              {!isLoading && !totalFiles && (
                <EmptyState
                  titleProps={{
                    title: t(search ? 'NO_RESULTS' : 'EMPTY_FOLDER'),
                  }}
                  totalColumns={columnsCount}
                />
              )}
              {!isLoading &&
                files.map((file, fileIndex) => (
                  <FileRow
                    key={file.id}
                    file={file}
                    index={fileIndex}
                    onClickFile={(fileValue: File, indexValue: number) =>
                      handleOnClickFile(fileValue, indexValue)
                    }
                  />
                ))}
            </HuTableBody>
          </HuTable>
          <FilePreview
            open={openPreview}
            currentFile={files[index]}
            onGoBack={handleGoBack}
            onGoForward={handleGoForward}
            isNavigationButtonGoBackDisabled={isNavigationButtonGoBackDisabled}
            isNavigationButtonGoForwardDisabled={
              isNavigationButtonGoForwardDisabled
            }
            isLoadingMedia={!files[index]}
            headerProps={{
              allowDownload: !disabledDownload,
              onClose: () => setOpenPreview(false),
            }}
          />
        </HuTableContainer>
        {totalFiles > 0 && (
          <HuTableLoader
            loadedCount={files.length}
            totalCount={totalFiles ?? 0}
            onLoadMore={fetchNextPage}
            onScrollToTop={handleScrollToTop}
          />
        )}
      </Stack>
    </FormProvider>
  );
};

export default FilesTable;
