import hydrajs from 'hydrajs';
import map from 'lodash/map';
import { AttachmentReducerConstants, AttachmentReducerDispatchType, ICaseFiles, IFileLocal, IUploadMetadata } from './AttachemntReducer';

export const updateUploadMetadata = (dispatch: AttachmentReducerDispatchType, localFile: IFileLocal, fileIndexToEdit: number, newUploadMetadata: IUploadMetadata) => {
    const editedLocalFile = { ...localFile, uploadProgress: { ...localFile.uploadProgress, ...newUploadMetadata } };
    dispatch({ type: AttachmentReducerConstants.caseLocalFileEdited, payload: { editedLocalFile, fileIndexToEdit } });
};

export const uploadAllFiles = async (dispatch: AttachmentReducerDispatchType, caseNumber: string, caseFiles: ICaseFiles) => {
    map(caseFiles.selectedLocalFiles, async (localFile, index) => {
        uploadFile(dispatch, caseNumber, localFile, caseFiles.selectedOriginalFiles[index], index);
    });
};

export const uploadFile = async (dispatch: AttachmentReducerDispatchType, caseNumber: string, localFile: IFileLocal, originalFile: File, index: number) => {
    if (!localFile.uploadability.ableToUpload) {return; }
    const uploadProgress = localFile.uploadProgress;
    // Do Not upload if already doing / done so
    if (uploadProgress.inProgress || uploadProgress.completed || uploadProgress.verifying) { return; }
    // For Metadata you must add x-amz-meta
    const putObjectRequest: any = {
        Body: originalFile, // use the original file for upload
        ContentLength: localFile.size,
        ContentType: localFile.type,
        Metadata: {
            'x-amz-meta-description': localFile.description,
            'x-amz-meta-fileName': localFile.name,
            'x-amz-meta-byteLength': localFile.size.toString(),
            'x-amz-meta-content-type': localFile.type
        }
    };
    try {
        const listener = (progress, abort) => {
            const decimal = progress.loaded / progress.total;
            const percent = decimal * 100;
            const verifyingUpdate = decimal === 1;
            const currentUploadProgress = Math.floor(percent);
            const currentUploadPayload: IUploadMetadata = {
                inProgress: true,
                verifying: verifyingUpdate,
                percentUploaded: currentUploadProgress,
                completed: false,
                uploadError: false,
                errorMessage: '',
                onAbort: undefined,
                aborted: false,
            };
            const onAbort = (abortedFileIndex) => {
                const abortPayload: IUploadMetadata = {
                    inProgress: false,
                    verifying: false,
                    percentUploaded: 0,
                    completed: false,
                    uploadError: false,
                    errorMessage: '',
                    onAbort: undefined,
                    aborted: true
                };
                updateUploadMetadata(dispatch, localFile, abortedFileIndex, abortPayload);
                abort();
            };
            currentUploadPayload.onAbort = onAbort;
            updateUploadMetadata(dispatch, localFile, index, currentUploadPayload);
        };
        const initialUploadPayload: IUploadMetadata = {
            inProgress: true,
            verifying: false,
            completed: false,
            uploadError: false,
            errorMessage: '',
            percentUploaded: 0,
            onAbort: undefined,
            aborted: false
        };
        updateUploadMetadata(dispatch, localFile, index, initialUploadPayload);
        await hydrajs.kase.attachments.uploadAttachmentS3(caseNumber,
            {
                description: localFile.description,
                fileName: localFile.name,
                isPrivate: false, // Not supporting private attachment using SE for now
                size: localFile.size
            },
            putObjectRequest,
            listener
        );

        const uploadPayload: IUploadMetadata = {
            inProgress: false,
            verifying: false,
            completed: true,
            uploadError: false,
            errorMessage: '',
            percentUploaded: 100,
            onAbort: undefined,
            aborted: false
        };
        updateUploadMetadata(dispatch, localFile, index, uploadPayload);
    } catch (error) {
        if (error.message === 'Request aborted by user') {
            // Show alert if needed
        } else {
            const uploadErrorPayload: IUploadMetadata = {
                inProgress: false,
                verifying: false,
                completed: false,
                uploadError: true,
                errorMessage: error.message,
                percentUploaded: 0,
                onAbort: undefined,
                aborted: false
            };
            updateUploadMetadata(dispatch, localFile, index, uploadErrorPayload);
        }
    }
};
