public class RiabuTokenUpdateJob implements Queueable, Database.AllowsCallouts {
 
    private String recordName;
    private String newAccessToken;
    private String newRefreshToken;
    //private Datetime expiryTime;
 
    public RiabuTokenUpdateJob(String recordName, String accessToken, String refreshToken) {
        this.recordName = recordName;
        this.newAccessToken = accessToken;
        this.newRefreshToken = refreshToken;
        //this.expiryTime = expiryTime;
    }
 
	public void execute(QueueableContext qc) {
        MetadataService.MetadataPort service = MetadataUtil.createService();
        MetadataService.IReadResult readResult =
            service.readMetadata('CustomMetadata', new String[] { 'RIABU_Integration__mdt.' + recordName });
        MetadataService.CustomMetadata cmdt =
            (MetadataService.CustomMetadata) readResult.getRecords()[0];
        // Keep existing field values
        List<MetadataService.CustomMetadataValue> updatedValues = cmdt.values;
        // Update Access Token
        upsertValue(updatedValues, 'Access_Token__c', newAccessToken);
        // Update Refresh Token only if returned
        if(String.isNotBlank(newRefreshToken)){
            upsertValue(updatedValues, 'Refresh_Token__c', newRefreshToken);
        }
        cmdt.values = updatedValues;
        MetadataService.SaveResult[] results =
            service.updateMetadata(new MetadataService.Metadata[] { cmdt });
        if (results[0].success) {
            System.debug('✅ CMDT Updated Successfully');
        } else {
            System.debug('❌ CMDT Update Failed: ' + results[0].errors[0].message);
        }
    }
    private void upsertValue(List<MetadataService.CustomMetadataValue> listVals, String fieldName, String fieldValue) {
        Boolean found = false;
        for(MetadataService.CustomMetadataValue v : listVals) {
            if(v.field == fieldName){
                v.value = fieldValue;
                found = true;
                break;
            }
        }
        if(!found){
            MetadataService.CustomMetadataValue newVal = new MetadataService.CustomMetadataValue();
            newVal.field = fieldName;
            newVal.value = fieldValue;
            listVals.add(newVal);
        }
    }
 
 
    private MetadataService.CustomMetadataValue createValue(String fieldName, String val) {
        MetadataService.CustomMetadataValue v = new MetadataService.CustomMetadataValue();
        v.field = fieldName;
        v.value = val;
        return v;
    }
}