public without sharing class RetrieveApprovalRecordsController {
    //Wrapper class to store the column values of data table
    public class SubmittedRecordsWrapper{
        @AuraEnabled public Id workItemId;
        @AuraEnabled public String recordId;
        @AuraEnabled public String relatedTo;
        @AuraEnabled public String recordName;
        @AuraEnabled public String nameUrl;
        @AuraEnabled public String submittedBy;
        @AuraEnabled public String submittercomment;
        @AuraEnabled public Date submittedDate;
        @AuraEnabled public String comments;
    }
    @AuraEnabled (cacheable=true)
    public static integer gettotalcount()
    {
        Integer icount = 0;
        //Add By Li Jun 20231026 Start
        //kk修改
        // List<ProcessInstanceWorkitem> piwList = new List<ProcessInstanceWorkitem>([SELECT ID,ProcessInstanceId  FROM ProcessInstanceWorkitem  WHERE (OriginalActorId = : UserInfo.getUserId() and ActorId = null) OR ActorId = : UserInfo.getUserId()]);
        List<ProcessInstanceWorkitem> piwList = new List<ProcessInstanceWorkitem>([SELECT ID,ProcessInstanceId  FROM ProcessInstanceWorkitem  WHERE  ActorId = : UserInfo.getUserId()]);
        Set<Id> piSet = new Set<Id>();
        for(ProcessInstanceWorkitem piwi:piwList){
            piSet.add(piwi.ProcessInstanceId);
        }
        //Add By Li Jun 20231026 Start
        for(ProcessInstance ps : [SELECT Id,TargetObjectId,TargetObject.Name,CreatedDate FROM ProcessInstance WHERE id in: piSet]){
            icount++;
        }
        return icount;
    }
    @AuraEnabled
    public static List<SubmittedRecordsWrapper> getSubmittedRecords(Integer queryLimit, Integer queryOffset){
        system.debug('queryLimit'+queryLimit);
        system.debug('queryOffset'+queryOffset);
        List<SubmittedRecordsWrapper> lstSubmissionWrapper = new List<SubmittedRecordsWrapper>();
        //Process instance stores the info of records submitted for approval,
        // Process instance work item are the records an approver sees while approving/rejecting, Process instance step stores approved/rejected record including approva;/rejection comments
        //Add By Li Jun 20231026 Start
        //DB202311350543 李文涛 修改
        // List<ProcessInstanceWorkitem> piwList = new List<ProcessInstanceWorkitem>([SELECT ID,ProcessInstanceId  FROM ProcessInstanceWorkitem  WHERE (OriginalActorId = : UserInfo.getUserId() and ActorId = null) OR ActorId = : UserInfo.getUserId()]);
        List<ProcessInstanceWorkitem> piwList = new List<ProcessInstanceWorkitem>([SELECT ID,ProcessInstanceId  FROM ProcessInstanceWorkitem  WHERE  ActorId = : UserInfo.getUserId()]);
        Set<Id> piSet = new Set<Id>();
        for(ProcessInstanceWorkitem piwi:piwList){
            piSet.add(piwi.ProcessInstanceId);
        }
        //Add By Li Jun 20231026 Start
        for(ProcessInstance ps : [SELECT Id,TargetObjectId,TargetObject.Name,CreatedDate,
                                    //DB202311350543 李文涛修改
                                 // (SELECT ID FROM WorkItems WHERE (OriginalActorId = : UserInfo.getUserId() and ActorId = null) OR ActorId = : UserInfo.getUserId()),
                                 (SELECT ID FROM WorkItems WHERE  ActorId = : UserInfo.getUserId()),
                                 (SELECT OriginalActor.Name,Comments FROM Steps WHERE StepStatus = 'Started') FROM ProcessInstance WHERE id in:piSet
                                 ORDER BY CreatedDate DESC LIMIT :queryLimit OFFSET :queryOffset]){
            if(!ps.WorkItems.isEmpty()){
                SubmittedRecordsWrapper objSubmittedRecordsWrapper = getSubmitRecord(ps);
                if(!ps.steps.isEmpty()){
                    objSubmittedRecordsWrapper.submittedBy = ps.steps[0].OriginalActor.Name;
                    if(ps.steps[0].Comments == '' || ps.steps[0].Comments == null)
                    objSubmittedRecordsWrapper.submittercomment = 'No comments from submitter';
                    else
                    objSubmittedRecordsWrapper.submittercomment = ps.steps[0].Comments;
                    lstSubmissionWrapper.add(objSubmittedRecordsWrapper);
                }
            }
        }
        system.debug(JSON.serialize(lstSubmissionWrapper));
        return lstSubmissionWrapper;
    }
    public static SubmittedRecordsWrapper getSubmitRecord(ProcessInstance ps){
        SubmittedRecordsWrapper objSubmittedRecordsWrapper = new SubmittedRecordsWrapper();
        if(ps!=null && ps.WorkItems!=null && ps.WorkItems.size() > 0){
            objSubmittedRecordsWrapper.workItemId = ps.WorkItems[0].Id;
        }
        objSubmittedRecordsWrapper.recordId = ps!=null && ps.TargetObjectId!=null?ps.TargetObjectId:null;
        objSubmittedRecordsWrapper.recordName = ps!=null && ps.TargetObject!=null ?ps.TargetObject.Name:'';
        if(ps!=null && ps.TargetObjectId!=null){
            objSubmittedRecordsWrapper.nameUrl = '/lightning/r/'+ ps.TargetObjectId+'/view';
        }    
        objSubmittedRecordsWrapper.comments = '';
        objSubmittedRecordsWrapper.relatedTo =getObjectName(ps.TargetObjectId);
        objSubmittedRecordsWrapper.submittedDate = ps!=null && ps.CreatedDate!=null? Date.newInstance(ps.CreatedDate.year(),ps.CreatedDate.month(),ps.CreatedDate.day()):Date.today();
        return objSubmittedRecordsWrapper;
    }
    public static String getObjectName(String recordId){
        //To get the label of the object name using Schema methods
        String keyPrefix = recordId.subString(0,3);
        String objectName = '';
        Map<String,Schema.SObjectType> sobjectTypeMap = Schema.getGlobalDescribe();
        for(String obj : sobjectTypeMap.keySet()){
            Schema.DescribeSObjectResult sobjectResult = sobjectTypeMap.get(obj).getDescribe();
            String getKeyPrefix = sobjectResult.getKeyPrefix();
            if(keyPrefix.equals(getKeyPrefix)){
                objectName = sobjectResult.getLabel();
                break;
            }
        }
        return objectName;
    }
    
    @AuraEnabled
    public static String processRecords(String processType,String strwraprecs){
        // system.debug('processType'+processType);
        // system.debug('wraprecs'+strwraprecs);
        // List<SubmittedRecordsWrapper> wraprecs = (List<SubmittedRecordsWrapper>)System.JSON.deserialize(strwraprecs, List<SubmittedRecordsWrapper>.class);
        // Map<string,SubmittedRecordsWrapper> mapSubmittedRecordsWrapper = new map<String,SubmittedRecordsWrapper>();
        // List<String> lstWorkItemIds = new List<String>();
        // for(SubmittedRecordsWrapper iwrap: wraprecs)
        // {
        //     mapSubmittedRecordsWrapper.put(iwrap.workItemId,iwrap);
        //     lstWorkItemIds.add(iwrap.workItemId);
        // }
        
        // //Approve,reject the record programmatically
        // String message = ''; 
        // Integer recordsProcessed = 0;
        // String comments = processType == 'Approve' ? 'Approved' : 'Rejected';
        // List<Approval.ProcessWorkitemRequest> lstWorkItemRequest = new List<Approval.ProcessWorkitemRequest>();//ProcessWorkitemRequest class has methods to programmatically process submitted records
        // for(String workItemId : lstWorkItemIds){
        //     Approval.ProcessWorkitemRequest objWorkItemRequest = new Approval.ProcessWorkitemRequest();
        //     if(mapSubmittedRecordsWrapper.containsKey(workItemId))
        //         objWorkItemRequest.setComments(mapSubmittedRecordsWrapper.get(workItemId).comments);
        //     else
        //         objWorkItemRequest.setComments(comments);
        //     objWorkItemRequest.setAction(processType);//approve or reject
        //     objWorkItemRequest.setWorkitemId(workItemId);
        //     lstWorkItemRequest.add(objWorkItemRequest);
        // }
        // Approval.ProcessResult[] lstProcessResult = Approval.process(lstWorkItemRequest,FALSE);//process method is used for approving/rejecting records depending on setAction attribute
        // for(Approval.ProcessResult processResult : lstProcessResult){
        //     if(processResult.isSuccess()){
        //         recordsProcessed++;
        //     }
        //     else{
        //         for(Database.Error error : processResult.getErrors()){
        //             message += error.getMessage();
        //         }
        //     }
        // }
        // if(recordsProcessed == lstWorkItemIds.size()){
        //     message = 'All records are '+comments+' successfully';
        // }
        // return message;
        return 'success';
    }
}