module analytics.modules.category_spend;

import handy_http_primitives : Optional;
import std.algorithm;
import std.array;

import analytics.data;
import profile.data;
import util.money : Currency;
import util.data : TimeRange;

CategorySpendData[] computeCategorySpend(
    ProfileDataSource ds,
    in Currency currency,
    in TimeRange timeRange,
    in Optional!ulong parentId
) {
    AnalyticsRepository repo = ds.getAnalyticsRepository();
    CategorySpendData[] allCategories = repo.getCategorySpendData(currency, timeRange);
    return allCategories
        .filter!(d => (
            parentId
            ? d.parentCategoryId && d.parentCategoryId.value == parentId.value
            : d.parentCategoryId.isNull
        ))
        .map!((category) {
            // For each category that we're reporting on, recursively sum up
            // the amount of the category and all its children.
            long totalRecursiveSum = sumAllChildCategoriesRecursive(category, allCategories);
            return CategorySpendData(
                category.categoryId,
                category.categoryName,
                category.categoryColor,
                category.parentCategoryId,
                totalRecursiveSum
            );
        })
        .array();
}

private long sumAllChildCategoriesRecursive(in CategorySpendData parentCategory, in CategorySpendData[] data) {
    long sum = parentCategory.amount;
    foreach (category; data) {
        if (category.parentCategoryId && category.parentCategoryId.value == parentCategory.categoryId) {
            sum += sumAllChildCategoriesRecursive(category, data);
        }
    }
    return sum;
}