/***********************************************************************************************************
 * Name         : SubUploadUtilRemoteController
 * Purpose      : Controller for SubUploadUtilRemoteVFPage
 **********************************************************************************************************/
public class SubUploadUtilRemoteController {

    @TestVisible
    private final String DELETE_WARNING = 'Uploading a new file will remove the previously uploaded file(s).';

    /**
     * @description Constructor
     *  Shows an Apex Message when the Sub Upload already have previously uploaded attachments
     */
    public SubUploadUtilRemoteController() {
        Id parentId = ApexPages.currentPage().getParameters().get('ParentId');
        if (!String.isBlank(parentId)) {
            Sub_Upload_Util__c fileUpload = SubUploadUtilRemoteController.getFileUpload(parentId);
            if (fileUpload != null && fileUpload.File_Uploaded__c) {
                ApexPages.Message message = new ApexPages.Message(
                    ApexPages.Severity.WARNING,
                    DELETE_WARNING
                );
                ApexPages.addMessage(message);
            }
        }
    }


    /**
     * @description Deletes existing attachments for the SubUpload
     * @param   Id  SubUpload Id
     */
    @RemoteAction
    public static void deletePreviousAttachments(Id parentId) {
        Database.delete([SELECT Id FROM Attachment WHERE ParentId = :parentId]);
    }

    /**
     * PRE-EXISTING Method
     * @description Processes a piece of the file being uploaded by the user
     * @param   String  subUpload Id
     * @param   String  attachment Id
     * @param   String  attachment Name
     * @param   String  piece of the file being processed 
     * @param   String  attachment description
     * @param   String  flag
     * @return  String process result
     */
    @RemoteAction
    public static String processChunk(
        String parentId,
        String attachmentId,
        String attachmentName,
        String base64ChunkPayload,
        String description,
        String fileUploadFlag
    ) {
        if (parentId != null) {
            Sub_Upload_Util__c fileUpload = getFileUpload(parentId);
            if (fileUpload != null) {
                if (base64ChunkPayload != null) {
                    Attachment attachment = getAttachment(attachmentId);
                    String newBody = '';
                    if (attachment.Body != null) {
                        newBody = attachment.Body.toString();
                    }
                    newBody += base64ChunkPayload;
                    attachment.Body = Blob.valueOf(newBody);
                    if (attachmentId == null) {
                        attachment.Name = attachmentName;
                        attachment.ParentId = fileUpload.Id;
                        attachment.Description = description;
                    }
                    upsert attachment;
                    if (fileUploadFlag == 'true') {
                        fileUpload.File_Uploaded__c = true;
                        fileUpload.Status__c = SubUploadBatchUtils.SUB_UPLOAD_READY_TO_PROCESS_STATUS;
                        if (fileUpload.Initiate_Process__c == false) {
                            fileUpload.Success_Record_Count__c = 0;
                            fileUpload.Failure_Record_count__c = 0;
                        }
                        update fileUpload;
                    }
                    return attachment.Id;
                } else {
                    return 'Attachment Body was null';
                }
            } else {
                return 'Parent record could not be found';
            }
        } else {
            return 'Parent Id was null';
        }
    }

    /**
     * PRE-EXISTING Method
     * @description Retrieves an Attachment by its Id
     * @param   String  Attachment Id
     * @return  Attachment record
     */
    @TestVisible
    private static Attachment getAttachment(String attachmentId) {
        List<Attachment> attachments = [SELECT Id, Body FROM Attachment WHERE Id = :attachmentId];
        if (attachments.isEmpty()) {
            Attachment a = new Attachment();
            return a;
        } else {
            return attachments[0];
        }
    }

    /**
     * PRE-EXISTING Method
     * @description Retrieves the SubUpload record by Id
     * @param   String  subUpload Id
     * @return  Sub_Upload_Util__c record
     */
    @TestVisible
    private static Sub_Upload_Util__c getFileUpload(String fileUploadId) {
        List<Sub_Upload_Util__c> fileUploads = [
            SELECT Id, Name, Failure_Record_count__c, Success_Record_Count__c, Initiate_Process__c, File_Uploaded__c
            FROM Sub_Upload_Util__c
            WHERE Id = :fileUploadId
        ];
        if (fileUploads.isEmpty()) {
            return null;
        } else {
            return fileUploads[0];
        }
    }
}
