/***********************************************************************************************************
 * Name         : ApprovalAttachmentsController
 * Purpose      : Controller of approvalAttachments LWC
 **********************************************************************************************************/

public with sharing class ApprovalAttachmentsController {
    public static final String ADVANCE_PAYMENT_OBJ_API_NAME = 'AdvancePayment__c';
    public static final String ADVANCE_PAYMENT_STATUS_CANCELED = 'Canceled';

    /**
     * @description Receives an Approval Request ID and return the list of
     * attachments related to its parent targetObjectId
     * @param recordId Approval Request ID
     * @return List of Attachments related to Approval Request target object ID
     */
    @AuraEnabled(cacheable=true)
    public static List<ContentDocumentLink> getAttachments(Id recordId, String lookupAPIName, String parentTargetField) {
        TargetObjectData targetObjectData = getTargetObjectData(recordId, lookupAPIName, parentTargetField);

        List<ContentDocumentLink> contentDocumentLinks = new List<ContentDocumentLink>();

        if (targetObjectData.recordId != null) {
            contentDocumentLinks = [
                SELECT
                    ContentDocumentId,
                    ContentDocument.Title,
                    ContentDocument.CreatedDate,
                    ContentDocument.FileExtension,
                    ContentDocument.ContentSize,
                    LinkedEntityId
                FROM
                    ContentDocumentLink
                WHERE
                    LinkedEntityId = :targetObjectData.recordId
            ];
        }
        return contentDocumentLinks;
    }

    /**
     * @description Get the targetObjectID related to the recordId parameter
     * or to the parent record, if specified.
     * @param recordId Approval Request ID
     * @return targetObjectID target parent of the attachment files
     */
    @AuraEnabled(cacheable=true)
    public static TargetObjectData getTargetObjectData(Id recordId, String lookupAPIName, String parentTargetField) {
        Id targetObjectId;
        String query = 'SELECT ';
        String objectAPIName = recordId.getSObjectType().getDescribe().getName();

        TargetObjectData targetObjectData = new TargetObjectData();

        if (lookupAPIName != null && parentTargetField != null) {
            query += lookupApiName + ' FROM ' + objectAPIName + ' WHERE Id = \'' + recordId + '\'';
            sObject sObj = Database.query(query);

            Id parentRecordId = Id.valueOf(String.valueOf(sObj.get(lookupApiName)));
            String parentObjectAPIName = parentRecordId.getSObjectType().getDescribe().getName();

            String parentQuery = 'SELECT ' + parentTargetField + ' FROM ' + parentObjectAPIName + ' WHERE Id = \'' + parentRecordId + '\'';
            sObject parentSObject = Database.query(parentQuery);
            targetObjectId = Id.ValueOf(String.valueOf(parentSObject.get(parentTargetField)));

            targetObjectData.recordId = Id.ValueOf(String.valueOf(parentSObject.get(parentTargetField)));
            targetObjectData.objectApiName = targetObjectData.recordId.getSObjectType().getDescribe().getName();
        } else {
            query += 'Id FROM ' + objectAPIName + ' WHERE Id = \'' + recordId + '\'';

            sObject sObj = Database.query(query);
            targetObjectId = Id.valueOf(String.valueOf(sObj.get('Id')));

            targetObjectData.recordId = recordId;
            targetObjectData.objectApiName = objectAPIName;
        }
        return targetObjectData;
    }

    /**
     * @description Check whether we should display the Add Files button
     * based on a custom logic for each object
     * @param recordId Advance Payment ID
     * @param sObjectApiName API Name of the object that owns the recordId param
     * @return Boolean indicating whether the Add Files should be visible or not
     */
    @AuraEnabled(cacheable=true)
    public static Boolean shouldDisplayAddFiles(String recordId, String sObjectApiName) {
        Boolean displayAddFiles;

        if (recordId != null && sObjectApiName != null) {
            if (sObjectApiName == ADVANCE_PAYMENT_OBJ_API_NAME) {
                AdvancePayment__c advancePayment = [SELECT Status__c FROM AdvancePayment__c WHERE Id = :recordId];
                displayAddFiles = advancePayment.Status__c != ADVANCE_PAYMENT_STATUS_CANCELED;
            }
        }
        return displayAddFiles;
    }

    public class TargetObjectData {
        @AuraEnabled public Id recordId;
        @AuraEnabled public String objectApiName;

        public TargetObjectData() {}

        public TargetObjectData(Id recordId, String objectApiName) {
            this.recordId = recordId;
            this.objectApiName = objectApiName;
        }
    }
}