// DoB means Days of Buffering

function ynabEnhancedDoB() {
    var YNABheader = document.getElementsByClassName("budget-header-flexbox")[0];
    var elementForAoM = document.getElementsByClassName("budget-header-days")[0];
    var elementForDoB = elementForAoM.cloneNode(true);

    var DoB = ynabEnhancedDoBCalculate();
    elementForDoB.children[0].innerText = DoB + " day" + (DoB == 1 ? "" : "s");
    elementForDoB.children[0].className = elementForDoB.children[0].className + " days-of-budgeting";
    elementForDoB.children[1].innerText = "Days of Buffering";
    elementForDoB.children[1].title = "Don't like AoM? Here you are this new shiny metric! Shows how many days you can live without income on your budget total considering average daily outflow.";    

    YNABheader.appendChild(elementForDoB);
}

function onlyUnique(value, index, self) { 
    return self.indexOf(value) === index;
}

function ynabEnhancedCheckTransactionTypes(transactions) {
    // There must be exactly 3 types that are described.
    var uniqueTransactionTypes = Array.from(transactions, (el) => el.displayItemType).filter(onlyUnique);
    var handeledTransactionTypes = ["subTransaction", "transaction", "scheduledTransaction"];
    var allTypesHandeled = (uniqueTransactionTypes.length == handeledTransactionTypes.length) && 
        uniqueTransactionTypes.every(function(element, index) {
            return element === handeledTransactionTypes[index]; 
        }); 
    if (!allTypesHandeled) {
        throw "Found unhandeled transaction type. " + uniqueTransactionTypes;
    }  
}

function ynabEnhancedDoBCalculate() {
    var accounts = ynab.YNABSharedLib.getBudgetViewModel_AllAccountTransactionsViewModel()._result;

    var firstTransactionDate = accounts.minTransactionDate._internalUTCMoment._d;
    var lastTransactionDate = accounts.maxTransactionDate._internalUTCMoment._d;
    var totalDays = (lastTransactionDate - firstTransactionDate)/3600/24/1000;

    var transactions = accounts.visibleTransactionDisplayItems;
    ynabEnhancedCheckTransactionTypes(transactions);
    // All subTransaction (comes from split) have their parent transaction so they shouldn't count.
    // scheduledTransaction shouldn't count too because they are not paid.
    var outflow_transactions = transactions.filter((el) => el.displayItemType == "transaction" 
                                                    && el.transferAccountId == null 
                                                    && el.outflow > 0);
    var totalOutflow = Array.from(outflow_transactions, (i) => i.outflow).reduce((a, b) => a + b, 0);
    var averageDailyOutflow = totalOutflow / totalDays;
    var budgetAccountsTotal = ynab.YNABSharedLib.getBudgetViewModel_SidebarViewModel()._result.getOnBudgetAccountsBalance();
    return Math.floor(budgetAccountsTotal/averageDailyOutflow);
}

function ynabEnhancedDoBInit() {
    var elementForAoM = document.getElementsByClassName("budget-header-days");
    var elementForDoB = document.getElementsByClassName('days-of-budgeting');
    if (elementForAoM.length == 1 && elementForDoB.length == 0) {
        ynabEnhancedDoB();
    }
    
    setTimeout(ynabEnhancedDoBInit, 250);
}

setTimeout(ynabEnhancedDoBInit, 250);

@@ -282,19 +282,22 @@
     var 
-DoB
+result
  = ynabE
@@ -361,19 +361,29 @@
 rText = 
+result%5B%22
 DoB
+%22%5D
  + %22 day
@@ -387,19 +387,29 @@
 day%22 + (
+result%5B%22
 DoB
+%22%5D
  == 1 ? 
@@ -517,24 +517,423 @@
 budgeting%22;%0A
+    elementForDoB.children%5B0%5D.title = %22Total outflow: %22 + ynab.YNABSharedLib.currencyFormatter.format(result%5B%22totalOutflow%22%5D) + %0A        %22%5CnTotal days of budgeting: %22 + result%5B%22totalDays%22%5D + %0A        %22%5CnAverage daily outflow: ~%22 + ynab.YNABSharedLib.currencyFormatter.format(result%5B%22averageDailyOutflow%22%5D) + %0A        %22%5CnAverage daily transactions: %22 + result%5B%22averageDailyTransactions%22%5D.toFixed(1);%0A
     elementF
@@ -1077,118 +1077,90 @@
 ric!
- Shows how many days you can live without income on your budget total considering average daily outflow.%22;    
+%22;%0A    elementForDoB.className = elementForDoB.className.replace(/%5Cbhidden%5Cb/,'');
 %0A%0A  
@@ -1361,73 +1361,31 @@
  // 
-There must be exactly 3 types that are described.%0A    var uniqueT
+Describe all handeled t
 rans
@@ -1394,88 +1394,43 @@
 tion
-T
+ t
 ypes 
-= Array.from(transactions, (el) =%3E el.displayItemType).filter(onlyUnique);
+and check that no other got.
 %0A   
@@ -1521,212 +1521,212 @@
 ion%22
-%5D;%0A    var allTypesHandeled = (uniqueTransactionTypes.length == handeledTransactionTypes.length) && %0A        uniqueTransactionTypes.every(function(element, index) %7B%0A            return element === handeled
+, %22scheduledSubTransaction%22%5D;%0A    var uniqueTransactionTypes = Array.from(transactions, (el) =%3E el.displayItemType).filter(onlyUnique);%0A    var allTypesHandeled = uniqueTransactionTypes.every(el =%3E unique
 Tran
@@ -1741,27 +1741,21 @@
 ypes
-%5Bindex%5D; %0A        %7D
+.includes(el)
 ); %0A
@@ -3092,16 +3092,31 @@
   return
+ %7B%0A        DoB:
  Math.fl
@@ -3159,17 +3159,204 @@
 Outflow)
-;
+,%0A        totalOutflow: totalOutflow,%0A        totalDays: totalDays,%0A        averageDailyOutflow: averageDailyOutflow,%0A        averageDailyTransactions: transactions.length/totalDays,%0A    %7D
 %0A%7D%0A%0Afunc

fix transaction type check, add stats to DoB tooltip