public with sharing class PaginatedListControllerLwc {
    @AuraEnabled
    public static PaginatedAccounts getAccountsPaginated(Integer pageSize, Integer pageToken, String sortField, String sortOrder) {
        system.debug('init soql'+ String.valueOf(pageSize)  + String.valueof(pageToken));
        PaginatedAccounts paginatedAccounts = new PaginatedAccounts();
        String paginatedQuery = 'SELECT Name, Type, Phone, NumberOfEmployees, Owner.Name'
                 + ' FROM Account'
                 + ' WITH SECURITY_ENFORCED';
        system.debug('sort field:'+sortField + '--'+sortOrder);
        if(sortField != null && sortOrder !=null) {
            paginatedQuery += ' ORDER BY '+ sortField +' '+ sortOrder;
        }
        paginatedQuery += ' LIMIT ' + pageSize;
        paginatedQuery += ' OFFSET ' + pageToken;
        system.debug('SOQL:' + paginatedQuery);
        paginatedAccounts.records = Database.query(paginatedQuery);
        Integer totalCount = [SELECT COUNT() FROM Account];

        paginatedAccounts.nextPageToken = (pageToken + pageSize < totalCount) ? pageToken + pageSize : null;
        paginatedAccounts.recordStart = pageToken + 1;
        paginatedAccounts.pageNumber = pageToken/pageSize + 1;
        Integer recordEnd = pageSize * paginatedAccounts.pageNumber;
        paginatedAccounts.recordEnd = totalCount >= recordEnd ? recordEnd : totalCount;
        paginatedAccounts.totalRecords = totalCount;
        return paginatedAccounts;
    }

    public class PaginatedAccounts {
        @AuraEnabled
        public List<Account> records;
        @AuraEnabled
        public Integer nextPageToken;
        @AuraEnabled
        public Integer pageNumber {get;set;}
        @AuraEnabled
        public Integer totalRecords {get;set;}
        @AuraEnabled
        public Integer recordStart {get;set;}
        @AuraEnabled
        public Integer recordEnd {get;set;}        
    }
}
