import { useMemo } from 'react';

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

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 } from '../../../constants';
import {
  addApplicationOfferStageFile,
  deleteApplicationOfferStageFile,
  uploadApplicationFile,
} from '../../../services';
import { type FileCardTypeWithId, type StageTypes } from '../../../types';
import { useApplicationFiles } from '../hooks/useApplicationFiles';

import { DeleteFileModal } from './DeleteFileModal';

type OfferFileProps = {
  title: string;
  stageFile?: FileAsset;
  applicationId: number;
  jobId: number;
  label: string;
  stageId: number;
  stageType: StageTypes.OFFER | StageTypes.OFFER_ACCEPTED;
};

export const OfferFile = ({
  title,
  stageFile,
  applicationId,
  jobId,
  label,
  stageType,
  stageId,
}: OfferFileProps) => {
  const { t } = useLokaliseTranslation(['ats', 'material_hu_only']);
  const files = useMemo(() => (stageFile ? [stageFile] : []), [stageFile]);

  const {
    uploadedFiles,
    setUploadedFiles,
    onUpload,
    handleDropRejected,
    deleteFile,
    addFilesToBackend,
    isLoadingDeleteFile,
  } = useApplicationFiles({
    onUploadFileService: uploadApplicationFile,
    onDeleteFileService: (fileId: number) =>
      deleteApplicationOfferStageFile({
        jobId,
        applicationId,
        fileId,
        stageType,
        stageId,
      }),
    onUploadFilesService: (fileIds: number[]) =>
      addApplicationOfferStageFile({
        jobId,
        applicationId,
        fileIds,
        stageType,
        stageId,
      }),
    onDeleteSuccess: () => {
      handleCloseDeleteOfferStageFileModal();
    },
    applicationId,
    jobId,
    files,
  });

  const {
    closeModal: closeDeleteOfferStageFileModal,
    showModal: showDeleteOfferStageFileModal,
    modal: deleteStageOfferFileModal,
  } = useModal<{ fileId: number; stageId: number }>(props => (
    <DeleteFileModal
      {...props}
      isLoading={isLoadingDeleteFile}
      onConfirm={({ fileId }) => {
        if (!fileId || !stageId) return;
        deleteFile(fileId);
      }}
      onClose={handleCloseDeleteOfferStageFileModal}
    />
  ));

  const handleCloseDeleteOfferStageFileModal = () => {
    closeDeleteOfferStageFileModal();
  };

  return (
    <Stack sx={{ gap: 1, width: '100%' }}>
      <Uploader
        {...{
          uploadFunction: onUpload,
          label,
          title,
          maxFiles: 1,
          acceptedTypes: ['image', 'msword', 'pdf'],
          fileSizeLimit: MAX_FILE_SIZE_BYTES,
          description: t('common.files_allowed.base', {
            formats: t('common.files_allowed.image_and_text'),
            size: MAX_FILE_SIZE_MB,
          }),
          value: uploadedFiles,
          showUploadButtonOnMaxFiles: false,
          triggerOnChangeWhenUploading: true,
          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: 1,
                fileSizeLimit: bytesToSize(MAX_FILE_SIZE_BYTES),
              },
            ),
            uploadFile: t('general:upload_file'),
            maxFilesError: t('material_hu_only:uploader.max_files_error', {
              maxFiles: 1,
            }),
            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;
              showDeleteOfferStageFileModal({ fileId: file.id, stageId });
            },
          },
          slotProps: {
            fileCard: {
              showDownloadButton: true,
              showRemoveUploadingButton: true,
            },
          },
          onChange: (newFiles: FileCardTypeWithId[]) => {
            if (newFiles.length < uploadedFiles.length) {
              // Removal — onRemove handles this via the confirmation modal
              return;
            }
            setUploadedFiles(newFiles);
            const stillUploading = newFiles.some(f => f.status === 'uploading');
            if (!stillUploading) {
              addFilesToBackend(
                newFiles
                  .map(file => file.id)
                  .filter(id => id !== undefined) as number[],
              );
            }
          },
        }}
      />
      {deleteStageOfferFileModal}
    </Stack>
  );
};
