import React, { useCallback, useState } from 'react';
import { apiMutate } from '../utilities';
import { Box } from '../UI';
import { AmbientCard } from '../UI/surfaces/cards/AmbientCard';
import { DragDropFileUpload } from './DragDropFileUpload';
import { LinearProgress } from '../UI';
import { List, ListItem, IconButton } from '@material-ui/core';
import { ConfigService } from '../configService/index';
import DeleteIcon from '@material-ui/icons/Delete';
import { DownloadIcon, ChromeCloseIcon } from '@fluentui/react-icons';
import { useTranslation } from 'react-i18next';
import { useHandleAxiosSnackbar } from '../utilities';
import { Divider } from '@material-ui/core';
import { AttachmentAction } from './enums/systemEnums';
import { FluentDialog } from '../UI';
import { FluentIconButton } from '../UI/inputs/buttons';
import './Attachments.css';
import { AmbientAutoComplete } from '../UI/inputs/textField';
const removeDuplicateFiles = (incomingFiles, existingFiles) => {
    const uniqueFiles = [];
    const duplicateFiles = [];
    incomingFiles.forEach((newFile) => {
        const exists = existingFiles.some((existingFile) => existingFile.name === newFile.name ||
            existingFile.fileName === newFile.name);
        if (exists) {
            duplicateFiles.push(newFile);
        }
        else {
            uniqueFiles.push(newFile);
        }
    });
    return { uniqueFiles, duplicateFiles };
};
export const Attachments = ({ allowedExtensions, MAX_FILE_SIZE_MB, filePreview, setFilePreview, currentAttachments, setCurrentAttachments, attachmentTypes, attachmentType, setAttachmentType, attachmentProgress, setAttachmentProgress, previousAttachments, setPreviousAttachments }) => {
    const [attachmentDialogOpen, setAttachmentDialogOpen] = useState(false);
    const [attachmentToDelete, setAttachmentToDelete] = useState(null);
    const [attachmentToDeleteIndex, setAttachmentToDeleteIndex] = useState(0);
    const [attachmentAction, setAttachmentAction] = useState(AttachmentAction.None);
    const { handleErrorSnackbar, handleSuccessSnackbar } = useHandleAxiosSnackbar();
    const { t } = useTranslation();
    const initiateAttachmentAction = useCallback((action, file, index) => {
        setAttachmentAction(action);
        setAttachmentToDelete(file);
        setAttachmentToDeleteIndex(index);
        setAttachmentDialogOpen(true);
    }, []);
    const handleAttachmentDeleteClick = useCallback((file, index) => {
        initiateAttachmentAction(AttachmentAction.Delete, file, index);
    }, [initiateAttachmentAction]);
    const handleAttachmentRemoveClick = useCallback((file, index) => {
        initiateAttachmentAction(AttachmentAction.Remove, file, index);
    }, [initiateAttachmentAction]);
    const handleCloseAttachmentDialog = useCallback(() => {
        setAttachmentAction(AttachmentAction.None);
        setAttachmentToDelete({});
        setAttachmentDialogOpen(false);
    }, []);
    const removeAttachmentFromList = useCallback((attachments, setAttachments) => {
        setAttachments((prev) => prev.filter((item, i) => i !== attachmentToDeleteIndex));
        handleSuccessSnackbar(t('Attachment Removed Successfully'));
        handleCloseAttachmentDialog();
    }, [
        attachmentToDeleteIndex,
        handleSuccessSnackbar,
        handleCloseAttachmentDialog,
        t
    ]);
    const deleteAttachment = useCallback(async () => {
        try {
            setAttachmentProgress(true);
            const filePayload = Object.assign(Object.assign({}, attachmentToDelete), { isDeleted: true });
            await apiMutate(ConfigService.productV1ApiUrl, `UdpTransactionAttachment/${attachmentToDelete.transactionAttachmentId}`, {
                method: 'put',
                data: filePayload
            });
            removeAttachmentFromList(previousAttachments, setPreviousAttachments);
        }
        catch (error) {
            handleErrorSnackbar('Failed to delete attachment', 'We encountered a system error while trying to delete the file. Please try again.');
            console.error(error);
        }
        finally {
            setAttachmentProgress(false);
            setAttachmentDialogOpen(false);
        }
    }, [
        attachmentToDelete,
        removeAttachmentFromList,
        previousAttachments,
        setPreviousAttachments,
        setAttachmentProgress,
        handleErrorSnackbar
    ]);
    const handleDownloadFile = useCallback(async (file) => {
        var _a;
        try {
            const response = await apiMutate(ConfigService.productV1ApiUrl, `UdpTransactionAttachment/${file.transactionAttachmentId}/udpDriveFile/download`, {});
            const url = response.data.link;
            const link = document.createElement('a');
            link.href = url;
            link.download = (_a = file.fileName) !== null && _a !== void 0 ? _a : file.name;
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
        catch (e) {
            console.error('Download failed', e);
        }
    }, []);
    const handleAddFiles = useCallback(async (files) => {
        const incomingFiles = Array.from(files);
        const validFiles = [];
        const invalidFiles = [];
        incomingFiles.forEach((file) => {
            const ext = file.name.split('.').pop().toLowerCase();
            const sizeInMB = file.size / (1024 * 1024);
            if (!allowedExtensions.includes(ext)) {
                invalidFiles.push(`${file.name} (Invalid file type)`);
            }
            else if (sizeInMB > MAX_FILE_SIZE_MB) {
                invalidFiles.push(`${file.name} (Exceeds ${MAX_FILE_SIZE_MB} MB)`);
            }
            else {
                validFiles.push(file);
            }
        });
        const allExistingFiles = [...previousAttachments, ...currentAttachments];
        const { uniqueFiles, duplicateFiles } = removeDuplicateFiles(validFiles, allExistingFiles);
        if (uniqueFiles.length > 0) {
            setCurrentAttachments((prev) => [...prev, ...uniqueFiles]);
        }
        if (invalidFiles.length > 0) {
            handleErrorSnackbar('Files not added', `The following files had errors:\n${invalidFiles.join('\n')}`);
            setFilePreview(true);
        }
        if (duplicateFiles.length > 0) {
            const duplicateNames = duplicateFiles.map((f) => f.name).join(', ');
            handleErrorSnackbar('Duplicates skipped', `The following files already exist and were not added: ${duplicateNames}`);
        }
    }, [
        allowedExtensions,
        MAX_FILE_SIZE_MB,
        previousAttachments,
        currentAttachments,
        setCurrentAttachments,
        handleErrorSnackbar,
        setFilePreview
    ]);
    const handleAttachmentTypeSelect = useCallback((attachmentType) => {
        setAttachmentType(attachmentType);
    }, [setAttachmentType]);
    const renderCurrentAttachments = () => {
        return currentAttachments.map((file, index) => (React.createElement(React.Fragment, { key: index }, index > 0 && React.createElement(Divider, { component: "li" }), React.createElement(ListItem, { className: "list-separator-item", style: { display: 'flex', justifyContent: 'space-between' } }, React.createElement(Box, null, file.fileName ? file.fileName : file.name), React.createElement(Box, null, React.createElement(IconButton, { onClick: () => handleAttachmentRemoveClick(file, index) }, React.createElement(DeleteIcon, null)))))));
    };
    const renderPreviousAttachments = () => {
        return previousAttachments.map((file, index) => {
            var _a;
            return (React.createElement(ListItem, { key: index, style: { display: 'flex', justifyContent: 'space-between' } }, React.createElement(Box, null, (_a = file.fileName) !== null && _a !== void 0 ? _a : file.name), React.createElement(Box, null, React.createElement(IconButton, { onClick: () => handleAttachmentDeleteClick(file, index) }, React.createElement(DeleteIcon, null)), React.createElement(IconButton, { onClick: () => handleDownloadFile(file) }, React.createElement(DownloadIcon, null)))));
        });
    };
    const renderConfirmationContent = () => {
        var _a;
        const isDeleteAction = attachmentAction === AttachmentAction.Delete;
        const actionVerb = isDeleteAction ? 'delete' : 'remove';
        const fileName = (_a = attachmentToDelete === null || attachmentToDelete === void 0 ? void 0 : attachmentToDelete.fileName) !== null && _a !== void 0 ? _a : attachmentToDelete === null || attachmentToDelete === void 0 ? void 0 : attachmentToDelete.name;
        return (React.createElement(React.Fragment, null, React.createElement("p", { className: 'deleteSubTitle' }, "Are you sure you want to ", actionVerb, " this attachment -", ' ', React.createElement("strong", null, `"${fileName}"`)), isDeleteAction && React.createElement("p", null, "This action cannot be undone.")));
    };
    return (React.createElement(React.Fragment, null, React.createElement("div", { className: "card-wrapper" }, attachmentProgress && (React.createElement("div", { className: "linear-progress" }, React.createElement(LinearProgress, null))), React.createElement(AmbientCard, { fullWidth: true, title: t('Add New Attachments'), variant: "secondary", subtitle: 'These files will be included with the submittal(s)' }, React.createElement(DragDropFileUpload, { title: "Drag and drop files here or click to browse", handleUploadFile: handleAddFiles, hideSelectFileButton: false, hideFilePreview: !filePreview, minHeight: "200px", maxHeight: "400px", multiple: true }), React.createElement(AmbientAutoComplete, { variant: "outlined", isMultiple: false, value: attachmentType, getOptionLabelFunction: (option) => option.name, onChange: handleAttachmentTypeSelect, options: attachmentTypes === null || attachmentTypes === void 0 ? void 0 : attachmentTypes.pageList, label: t('Select Attachment Type'), required: true })), (currentAttachments === null || currentAttachments === void 0 ? void 0 : currentAttachments.length) > 0 && (React.createElement(AmbientCard, { fullWidth: true, title: t('Current Attachments'), subtitle: `${currentAttachments.length} file(s) attached` }, React.createElement(List, null, renderCurrentAttachments()))), previousAttachments.length > 0 && (React.createElement(AmbientCard, { fullWidth: true, title: t('Previous Attachments') }, React.createElement(List, null, renderPreviousAttachments())))), React.createElement(FluentDialog, { title: React.createElement("div", { className: 'deleteTitle' }, React.createElement("span", null, attachmentAction === AttachmentAction.Delete
            ? t('Delete Attachment')
            : t('Remove Attachment')), React.createElement(FluentIconButton, { "aria-label": "close", icon: ChromeCloseIcon, onClick: handleCloseAttachmentDialog })), message: renderConfirmationContent(), labelOne: attachmentAction === AttachmentAction.Delete
            ? t('Delete')
            : t('Remove'), actionOne: attachmentAction === AttachmentAction.Delete
            ? deleteAttachment
            : () => removeAttachmentFromList(currentAttachments, setCurrentAttachments), labelTwo: t('Cancel'), actionTwo: handleCloseAttachmentDialog, open: attachmentDialogOpen, handleClose: handleCloseAttachmentDialog, fullWidth: true })));
};
//# sourceMappingURL=Attachments.js.map