Hi orolalovelyjoy24gmail, great questions.
1. For the Initialization of the variable NextLink, set it initially to https://graph.microsoft.com/v1.0/applications?$select=id,appId,displayName,passwordCredentials,keyCredentials&$top=999
In the Update NextLink where we update this variable, there's no dynamic @odata.nextlink property, so for the value, assuming your Parse JSON step right after your Get Azure AD Application list graph query is called the default name of "Parse JSON", you can just use the expression body('Parse_JSON')?['@odata.nextlink'] and even though it's not in the json schema if it exists in the response, it will find it, if not it will be null (which will end the do until loop.)
2. For this section, you create 3 composes-
* EndTimeTickValue: ticks(item()?['endDateTime']) <--This converts the endDateTime property of the app to ticks
* StartTimeTickValue: ticks(utcnow()) <--This converts the current time to ticks
* DifferenceAsDays: div(div(div(mul(sub(outputs('EndTimeTickValue'),outputs('StartTimeTickValue')),100),1000000000) , 3600), 24) <--This calculates the difference of the endDateTime to now
Then set the variable "daysTilExpiration" to the outputs of the "DifferenceAsDays"
3. To do this, instead of putting in that condition to check if the expiration date is > or < than the given value and only having a True or False, I'd probably put in a SWITCH in its place and then one branch would followed if the expiration date is, for example, 0-30 days, the next branch would be 31-60 days, and the next would be 61-90 days for example. Then in each branch off that switch you would have different emails