import { type FC } from 'react';
import { Helmet } from 'react-helmet-async';
import { FormProvider } from 'react-hook-form';
import { useQueryClient } from 'react-query';
import { useNavigate, useParams } from 'react-router-dom';

import { useDebounce } from '@material-hu/hooks/useDebounce';
import { useHuPagination } from '@material-hu/hooks/useHuPagination';
import { useModal } from '@material-hu/hooks/useModal';
import { IconFileUpload, IconFolderPlus } from '@material-hu/icons/tabler';
import Box from '@material-hu/mui/Box';
import Stack from '@material-hu/mui/Stack';

import HuMenuList from '@material-hu/components/composed-components/MenuList';
import HuBreadcrumbs from '@material-hu/components/design-system/Breadcrumbs';
import Button from '@material-hu/components/design-system/Buttons/Button';

import { type DocumentFolder } from 'src/types/documents';
import { insertIf } from 'src/utils/arrayUtils';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { useDocuments } from '../hooks/useDocuments';
import { useDocumentsPermissions } from '../hooks/useDocumentsPermissions';
import { documentsKeys } from '../queries';
import { documentsRoutes } from '../routes';

import DocumentsTable from './components/DocumentsTable';
import NewFolder from './components/NewFolder';

const DocumentsList: FC = () => {
  const navigate = useNavigate();
  const { id } = useParams();
  const currentFolderId = id && parseInt(id);
  const { t } = useLokaliseTranslation('documents');
  const title = t('PERSONAL_DOCUMENTS');
  const { canCreateDocuments, isFolderResponsible } = useDocumentsPermissions();
  const queryClient = useQueryClient();

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

  const debouncedSearch = useDebounce(params.search);

  const paginationAndOrder = {
    ...params.pagination,
    search: debouncedSearch || undefined,
    orderBy: params.orderBy,
    order: params.order,
  };

  const formattedFilterParams = {
    ...paginationAndOrder,
    folderIds: currentFolderId ? [currentFolderId] : null,
    ownerIds: null,
    minDate: null,
    maxDate: null,
    signatureStatuses: null,
  };

  const {
    documentsList,
    foldersList,
    totalCount,
    currentFolder,
    loadingFolders,
    loadingCurrentFolder,
    loadingDocuments,
    fetchNextFolderPage,
    fetchNextDocumentPage,
    isFetchingNextPage,
  } = useDocuments({
    params: paginationAndOrder,
    currentFolderId: Number(currentFolderId),
    formattedFilterParams: formattedFilterParams,
  });

  const {
    modal: newFolderModal,
    showModal: showNewFolderModal,
    closeModal: closeNewFolderModal,
  } = useModal<{ folder: DocumentFolder }>(
    ({ folder }) => (
      <NewFolder
        onCloseModal={() => {
          queryClient.invalidateQueries(documentsKeys.all());
          closeNewFolderModal();
        }}
        editingFolder={folder}
      />
    ),
    { maxWidth: 'sm', fullWidth: true },
  );

  const navigateToFolder = (folderId?: number) =>
    navigate(
      folderId ? documentsRoutes.folder(folderId) : documentsRoutes.base(),
    );

  const breadOptions = [
    {
      title: t('HOME'),
      id: null,
      onClick: () => navigateToFolder(undefined),
    },
    ...insertIf(!!currentFolder, {
      title: currentFolder?.name!,
      id: currentFolder?.id!,
      onClick: () => navigateToFolder(currentFolder?.id),
    }),
  ];

  const menuOptions = [
    {
      title: t('BULK_FILES'),
      onClick: () => navigate(documentsRoutes.bulkUpload()),
    },
  ];

  const handleNavigateToUploadocuments = () => {
    navigate(documentsRoutes.newDocument(Number(currentFolderId)));
  };

  const handleShowNewFolderModal = () => {
    showNewFolderModal({ folder: currentFolder });
  };

  return (
    <FormProvider {...form}>
      {newFolderModal}
      <Helmet>
        <title>{formatTitle(title)}</title>
      </Helmet>
      <Stack
        sx={{
          flexDirection: 'row',
          gap: 1,
          justifyContent: currentFolder ? 'space-between' : 'flex-end',
          alignItems: 'center',
          pt: 3,
        }}
      >
        {currentFolder && <HuBreadcrumbs links={breadOptions} />}
        <Stack sx={{ flexDirection: 'row', gap: 1 }}>
          {canCreateDocuments && !currentFolder && (
            <Button
              variant="contained"
              startIcon={<IconFolderPlus />}
              onClick={handleShowNewFolderModal}
            >
              {t('new_folder')}
            </Button>
          )}
          {(canCreateDocuments || isFolderResponsible) && currentFolder && (
            <Button
              variant="contained"
              startIcon={<IconFileUpload />}
              onClick={handleNavigateToUploadocuments}
            >
              {t('upload_documents')}
            </Button>
          )}
          {(canCreateDocuments || isFolderResponsible) && (
            <HuMenuList options={menuOptions} />
          )}
        </Stack>
      </Stack>
      <Box sx={{ mt: 3 }}>
        <DocumentsTable
          Search={<Search />}
          data={currentFolderId ? documentsList : foldersList}
          currentFolder={currentFolder}
          isLoading={loadingFolders || loadingCurrentFolder || loadingDocuments}
          navigateToFolder={navigateToFolder}
          onEditFolder={showNewFolderModal}
          TableSortingHeader={HuTableSortingHeader}
          fetchNextPage={
            currentFolderId ? fetchNextDocumentPage : fetchNextFolderPage
          }
          totalCount={totalCount || 0}
          isFetchingNextPage={isFetchingNextPage}
        />
      </Box>
    </FormProvider>
  );
};

export default DocumentsList;
