/** biome-ignore-all lint/correctness/useHookAtTopLevel: false positive hook is used in useDrawerV2 */

import { useRef, useState } from 'react';
import { useQueryClient } from 'react-query';

import Stack from '@material-hu/mui/Stack';
import { type FileAsset } from '@material-hu/types/attachments';

import Alert from '@material-hu/components/design-system/Alert';
import { type DrawerProps } from '@material-hu/components/design-system/Drawer';
import Uploader from '@material-hu/components/design-system/Uploader';

import { bytesToSize } from 'src/utils/filesUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import {
  MAX_FILE_SIZE_BYTES,
  MAX_FILE_SIZE_MB,
  MAX_FILES,
} from '../../../constants';
import { applicantsKeys } from '../../../queries';
import {
  addApplicationStageFiles,
  deleteApplicationStageFile,
  uploadApplicationFile,
} from '../../../services';
import { type FileCardTypeWithId } from '../../../types';

import { useApplicationFiles } from './useApplicationFiles';

type UseFilesDrawerContentProps = {
  onClose: () => void;
  applicationId: number;
  jobId: number;
};

type DrawerOpenProps = {
  files?: FileAsset[];
  stageId: number;
};

export const useFilesDrawerContent =
  ({ onClose, applicationId, jobId }: UseFilesDrawerContentProps) =>
  ({ files = [], stageId }: DrawerOpenProps) => {
    const { t } = useLokaliseTranslation(['ats', 'material_hu_only']);
    const [showFooter, setShowFooter] = useState(false);
    const scrollableRef = useRef<HTMLDivElement>(null);
    const queryClient = useQueryClient();
    const {
      uploadedFiles,
      setUploadedFiles,
      onUpload,
      handleDropRejected,
      deleteFile,
      addFilesToBackend,
    } = useApplicationFiles({
      onUploadFileService: uploadApplicationFile,
      onDeleteFileService: (fileId: number) =>
        deleteApplicationStageFile({ jobId, applicationId, fileId, stageId }),
      onUploadFilesService: (fileIds: number[]) =>
        addApplicationStageFiles({ jobId, applicationId, fileIds, stageId }),
      onUploadSuccess: () => {
        setShowFooter(true);
        if (scrollableRef.current) {
          scrollableRef.current.scrollTo({
            top: scrollableRef.current.scrollHeight,
            behavior: 'smooth',
          });
        }
      },
      onDeleteSuccess: () => setShowFooter(false),
      applicationId,
      jobId,
      files,
    });

    const handleClose = () => {
      setShowFooter(false);
      onClose();
      if (files.length !== uploadedFiles.length) {
        queryClient.invalidateQueries(
          applicantsKeys.applicationDetail(jobId, applicationId),
        );
      }
    };

    return {
      children: (
        <Stack
          sx={{ gap: 1, width: '100%', overflowY: 'auto' }}
          ref={scrollableRef}
        >
          <Uploader
            {...{
              uploadFunction: onUpload,
              triggerOnChangeWhenUploading: true,
              helperText: t('job_application.files.footer'),
              label: t('job_application.files.description'),
              sx: {
                '& .MuiTypography-root:first-child': {
                  fontWeight: theme => theme.typography.fontWeightRegular,
                },
              },
              maxFiles: MAX_FILES,
              acceptedTypes: [
                'pdf',
                'image',
                'msword',
                'compressed',
                'video',
                'xml',
              ],
              fileSizeLimit: MAX_FILE_SIZE_BYTES,
              description: t('common.files_allowed.all', {
                size: MAX_FILE_SIZE_MB,
              }),
              value: uploadedFiles,
              showUploadButtonOnMaxFiles: false,
              onDropRejected: handleDropRejected,
              text: {
                title: t('material_hu_only:uploader.title'),
                description: t(
                  'material_hu_only:uploader.allowed_with_max_files_and_formats_size_limit',
                  {
                    count: MAX_FILES,
                    fileSizeLimit: bytesToSize(MAX_FILE_SIZE_BYTES),
                  },
                ),
                uploadFile: t('general:upload_file'),
                maxFilesError: t('material_hu_only:uploader.max_files_error', {
                  maxFiles: MAX_FILES,
                }),
                someFileNotUploaded: t(
                  'material_hu_only:uploader.some_file_not_uploaded',
                ),
                fileNotUploaded: t(
                  'material_hu_only:uploader.file_not_uploaded',
                ),
              },
              fileCardProps: {
                onRemove: (file: FileCardTypeWithId) => {
                  if (!file.id) return;
                  deleteFile(file.id);
                },
              },
              slotProps: {
                fileCard: {
                  showDownloadButton: true,
                  showRemoveUploadingButton: true,
                },
              },
              onChange: (newFiles: FileCardTypeWithId[]) => {
                setUploadedFiles(newFiles);
                addFilesToBackend(
                  newFiles
                    .map(file => file.id)
                    .filter(id => id !== undefined) as number[],
                );
              },
            }}
          />
        </Stack>
      ),
      title: t('job_application.files.add_title'),
      onClose: () => handleClose(),
      secondaryButtonProps: {
        children: t('general:close'),
        onClick: () => handleClose(),
        variant: 'secondary',
        fullWidth: true,
      },
      footer: showFooter ? (
        <Alert
          severity="success"
          title={t('job_application.files.success')}
          hasClose={false}
        />
      ) : undefined,
    } as DrawerProps;
  };
