/***********************************************************************************************************
 * Name         : CancelApprovalRequestController
 * Purpose      : Controller of cancelApprovalRequest LWC
 **********************************************************************************************************/

public without sharing class CancelApprovalRequestController {
    /**
     * @description Reject/Cancel the ProcessInstanceWorkItem related to the ID
     * provided by LWC
     * @param advancePaymentId ProcessInstanceWorkItem ID
     * @return Id of the related Payment Type
     */
    @AuraEnabled
    public static void cancelApprovalRequest(
        Id advancePaymentId,
        String advancePaymentStatus,
        String advancePaymentClientName,
        String reasonForCancellation
    ) {
        try {
            AdvancePayment__c payment = new AdvancePayment__c(
                Id = advancePaymentId,
                LabelClientName__c = String.isNotBlank(advancePaymentClientName)
                    ? AP_Constants.CANCELLED_PREFIX + advancePaymentClientName
                    : AP_Constants.CANCELLED_PREFIX.removeEnd(' - '),
                Canceled_By__c = UserInfo.getName(),
                Status__c = AP_Constants.ADVANCE_PAYMENT_CANCELED_STATUS,
                RefusalReason__c = reasonForCancellation
            );

            if (
                advancePaymentStatus == AP_Constants.ADVANCE_PAYMENT_PENDING_STATUS ||
                advancePaymentStatus == AP_Constants.ADVANCE_PAYMENT_PENDING_MILESTONE_APPROVAL_STATUS
            ) {
                List<ProcessInstanceWorkItem> workItems = [
                    SELECT Id
                    FROM ProcessInstanceWorkitem
                    WHERE ProcessInstance.TargetObjectId = :advancePaymentId
                ];
                if (workItems.isEmpty()) {
                    AuraHandledException e = new AuraHandledException(AP_Constants.ERROR_MESSAGE_RECORD_UPDATED_RETRY);
                    e.setMessage(AP_Constants.ERROR_MESSAGE_RECORD_UPDATED_RETRY);
                    throw e;
                } else {
                    List<Approval.ProcessWorkitemRequest> requests = new List<Approval.ProcessWorkitemRequest>();

                    for (ProcessInstanceWorkItem workItem : workItems) {
                        Approval.ProcessWorkitemRequest request = new Approval.ProcessWorkitemRequest();
                        request.setWorkitemId(workItem.Id);
                        request.setAction(AP_Constants.APPROVAL_PROCESS_ACTION_REJECT);
                        requests.add(request);
                    }

                    TriggerControl.disableTrigger(AdvancePaymentTriggerHandler.SELF, TriggerOperation.BEFORE_UPDATE);

                    Approval.ProcessResult[] processResults = Approval.process(requests);

                    TriggerControl.enableTrigger(AdvancePaymentTriggerHandler.SELF, TriggerOperation.BEFORE_UPDATE);

                    for (Approval.ProcessResult result : processResults) {
                        if (!result.isSuccess()) {
                            AuraHandledException e = new AuraHandledException(
                                AP_Constants.ERROR_MESSAGE_RECORD_UPDATED_RETRY
                            );
                            e.setMessage(AP_Constants.ERROR_MESSAGE_RECORD_UPDATED_RETRY);
                            throw e;
                        }
                    }
                }
            }

            update payment;
        } catch (Exception e) {
            ErrorLogger.logError(e);
            throw new AuraHandledException(AP_Constants.ERROR_MESSAGE_FOR_CANCEL_REQUEST + e.getMessage());
        }
    }
}