"use strict";
/**
 * network controller
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTrend = void 0;
const strapi_1 = require("@strapi/strapi");
const helpers_1 = require("../../../utils/helpers");
const campus_1 = require("../../campus/controllers/campus");
exports.default = strapi_1.factories.createCoreController("api::network.network", ({ strapi }) => ({
    async org(ctx) {
        let entriesArray = [];
        let entriesToSum = [];
        let entries = ctx.query.entries || false;
        let networks = await strapi.entityService.findMany("api::network.network");
        for (let i = 0; i < networks.length; i++) {
            let id = networks[i].id;
            let res = await getSummary(strapi, id);
            entriesArray.push({ name: networks[i].name, summary: res });
            entriesToSum.push(res);
        }
        if (entries) {
            ctx.body = {
                data: entriesArray,
                meta: {},
            };
            return;
        }
        ctx.body = {
            data: { summary: sumAllValues(entriesToSum) },
            meta: {},
        };
    },
    async network(ctx) {
        const type = ctx.query.type || "";
        const id = ctx.params.id;
        let entries = ctx.query.entries || false;
        let entriesArray = [];
        let network = await strapi.entityService.findOne("api::network.network", id, {
            populate: "*",
        });
        if (!network) {
            return;
        }
        if (entries) {
            for (const campus of network.campuses) {
                let theId = campus.id;
                let res = await campusSummary(strapi, theId);
                entriesArray.push({ name: campus.name, summary: res });
            }
            ctx.body = {
                data: (0, campus_1.omitFieldsRecursively)(entriesArray),
                meta: {},
            };
            return;
        }
        const year = (0, helpers_1.getYearMonthsFromToday)();
        if (entries) {
            for (let i = 0; i < year.length; i++) {
                if (i == year.length - 1) {
                    break;
                }
                let month = year[i];
                let previousMonth = year[i + 1];
                let currentGiving = await strapi.entityService
                    .findMany("api::mavuno-giving.mavuno-giving", {
                    filters: {
                        date: {
                            $gte: month.startDate,
                            $lte: month.endDate,
                        },
                        network: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.total + acc, 0));
                let previousGiving = await strapi.entityService
                    .findMany("api::mavuno-giving.mavuno-giving", {
                    filters: {
                        date: {
                            $gte: previousMonth.startDate,
                            $lte: previousMonth.endDate,
                        },
                        network: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.total + acc, 0));
                let currentExpense = await strapi.entityService
                    .findMany("api::expense.expense", {
                    filters: {
                        date: {
                            $gte: month.startDate,
                            $lte: month.endDate,
                        },
                        network: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.amount + acc, 0));
                let previousExpense = await strapi.entityService
                    .findMany("api::expense.expense", {
                    filters: {
                        date: {
                            $gte: previousMonth.startDate,
                            $lte: previousMonth.endDate,
                        },
                        network: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.amount + acc, 0));
                let currentRegisteredMembers = await strapi.entityService.count("api::member.member", {
                    filters: {
                        createdAt: {
                            $gte: month.startDate,
                            $lte: month.endDate,
                        },
                        network: {
                            id: id,
                        },
                    },
                });
                let previousRegisteredMembers = await strapi.entityService.count("api::member.member", {
                    filters: {
                        createdAt: {
                            $gte: previousMonth.startDate,
                            $lte: previousMonth.endDate,
                        },
                        network: {
                            id: id,
                        },
                    },
                });
                let allocationThisMonth = await strapi.entityService
                    .findMany("api::money-allocation.money-allocation", {
                    filters: {
                        date: {
                            $gte: month.startDate,
                            $lte: month.endDate,
                        },
                        network: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.amount + acc, 0));
                let allocationLastMonth = await strapi.entityService
                    .findMany("api::money-allocation.money-allocation", {
                    filters: {
                        date: {
                            $gte: previousMonth.startDate,
                            $lte: previousMonth.endDate,
                        },
                        network: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.amount + acc, 0));
                let balanceThisMonth = allocationThisMonth - currentExpense;
                let balanceLastMonth = allocationLastMonth - previousExpense;
                let percentageOfAllocation = balanceThisMonth / allocationThisMonth;
                entriesArray.push({
                    month: month.name,
                    date: month.startDate,
                    members: {
                        thisMonth: currentRegisteredMembers,
                        lastMonth: previousRegisteredMembers,
                        trend: getTrend(currentRegisteredMembers, previousRegisteredMembers),
                    },
                    giving: {
                        thisMonth: currentGiving,
                        lastMonth: previousGiving,
                        trend: getTrend(currentGiving, previousGiving),
                    },
                    expense: {
                        thisMonth: currentExpense,
                        lastMonth: previousExpense,
                        trend: getTrend(currentExpense, previousExpense),
                        percentageOfAllocation: percentageOfAllocation,
                    },
                    allocation: {
                        thisMonth: allocationThisMonth,
                        lastMonth: allocationLastMonth,
                        trend: getTrend(allocationThisMonth, allocationLastMonth),
                    },
                    balance: {
                        thisMonth: balanceThisMonth,
                        lastMonth: balanceLastMonth,
                        percentageOfAllocation: percentageOfAllocation,
                    },
                });
            }
            ctx.body = { data: (0, campus_1.omitFieldsRecursively)(entriesArray), meta: {} };
            return;
        }
        if (id) {
            let data = await getSummary(strapi, id);
            if (type === "attendances") {
                ctx.body = {
                    data: data === null || data === void 0 ? void 0 : data.attendances,
                    meta: {},
                };
                return;
            }
            ctx.body = {
                data: (0, campus_1.omitFieldsRecursively)(data),
                meta: {},
            };
        }
        else {
            ctx.body = { data: [], meta: {} };
        }
    },
    async campus(ctx) {
        const type = ctx.query.type || "";
        let entries = ctx.query.entries || false;
        let entriesArray = [];
        const id = ctx.params.id;
        const year = (0, helpers_1.getYearMonthsFromToday)();
        const data = await campusSummary(strapi, id);
        if (type === "attendances") {
            ctx.body = {
                data: data === null || data === void 0 ? void 0 : data.attendances,
                meta: {},
            };
            return;
        }
        if (entries) {
            for (let i = 0; i < year.length; i++) {
                if (i == year.length - 1) {
                    break;
                }
                let month = year[i];
                let previousMonth = year[i + 1];
                let currentGiving = await strapi.entityService
                    .findMany("api::mavuno-giving.mavuno-giving", {
                    filters: {
                        date: {
                            $gte: month.startDate,
                            $lte: month.endDate,
                        },
                        campus: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.total + acc, 0));
                let previousGiving = await strapi.entityService
                    .findMany("api::mavuno-giving.mavuno-giving", {
                    filters: {
                        date: {
                            $gte: previousMonth.startDate,
                            $lte: previousMonth.endDate,
                        },
                        campus: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.total + acc, 0));
                let currentExpense = await strapi.entityService
                    .findMany("api::expense.expense", {
                    filters: {
                        date: {
                            $gte: month.startDate,
                            $lte: month.endDate,
                        },
                        campus: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.amount + acc, 0));
                let previousExpense = await strapi.entityService
                    .findMany("api::expense.expense", {
                    filters: {
                        date: {
                            $gte: previousMonth.startDate,
                            $lte: previousMonth.endDate,
                        },
                        campus: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.amount + acc, 0));
                let currentRegisteredMembers = await strapi.entityService.count("api::member.member", {
                    filters: {
                        createdAt: {
                            $gte: month.startDate,
                            $lte: month.endDate,
                        },
                        campus: {
                            id: id,
                        },
                    },
                });
                let previousRegisteredMembers = await strapi.entityService.count("api::member.member", {
                    filters: {
                        createdAt: {
                            $gte: previousMonth.startDate,
                            $lte: previousMonth.endDate,
                        },
                        campus: {
                            id: id,
                        },
                    },
                });
                let allocationThisMonth = await strapi.entityService
                    .findMany("api::money-allocation.money-allocation", {
                    filters: {
                        date: {
                            $gte: month.startDate,
                            $lte: month.endDate,
                        },
                        campus: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.amount + acc, 0));
                let allocationLastMonth = await strapi.entityService
                    .findMany("api::money-allocation.money-allocation", {
                    filters: {
                        date: {
                            $gte: previousMonth.startDate,
                            $lte: previousMonth.endDate,
                        },
                        campus: {
                            id: id,
                        },
                    },
                })
                    .then((it) => it.reduce((acc, curr) => curr.amount + acc, 0));
                let balanceThisMonth = allocationThisMonth - currentExpense;
                let balanceLastMonth = allocationLastMonth - previousExpense;
                let percentageOfAllocation = balanceThisMonth / allocationThisMonth;
                entriesArray.push({
                    month: month.name,
                    date: month.startDate,
                    summary: {
                        month: month.name,
                        date: month.startDate,
                        members: {
                            thisMonth: currentRegisteredMembers,
                            lastMonth: previousRegisteredMembers,
                            trend: getTrend(currentRegisteredMembers, previousRegisteredMembers),
                        },
                        giving: {
                            thisMonth: currentGiving,
                            lastMonth: previousGiving,
                            trend: getTrend(currentGiving, previousGiving),
                        },
                        expenses: {
                            thisMonth: currentExpense,
                            lastMonth: previousExpense,
                            trend: getTrend(currentExpense, previousExpense),
                            percentageOfAllocation: percentageOfAllocation,
                        },
                        allocation: {
                            thisMonth: allocationThisMonth,
                            lastMonth: allocationLastMonth,
                            trend: getTrend(allocationThisMonth, allocationLastMonth),
                        },
                        balance: {
                            thisMonth: balanceThisMonth,
                            lastMonth: balanceLastMonth,
                            percentageOfAllocation: percentageOfAllocation,
                        },
                    },
                });
            }
            ctx.body = { data: entriesArray, meta: {} };
            return;
        }
        ctx.body = { data, meta: {} };
    },
}));
function compareMonths(a, b) {
    const monthsOrder = [
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December",
    ];
    return monthsOrder.indexOf(a.month) - monthsOrder.indexOf(b.month);
}
async function getSummary(strapi, id) {
    // get dates to compare with
    const entry = {
        attendances: {},
    };
    // const today = new Date();
    // const midnight = new Date(today.setHours(0, 0, 0, 0));
    // const tomorrow = new Date(midnight);
    // tomorrow.setDate(midnight.getDate() + 1);
    const year = (0, helpers_1.getYearMonthsFromToday)();
    const months = year.map((it) => it.startDate.toLocaleString("en-US", { month: "short" }));
    // const thirtyDaysAgo = new Date(new Date().setDate(today.getDate() - 30));
    // const sixtyDaysAgo = new Date(new Date().setDate(today.getDate() - 60));
    if (id) {
        // get associated network data
        let network = await strapi.entityService.findOne("api::network.network", id, {
            populate: "*",
        });
        entry["network"] = {};
        entry["network"]["name"] = network.name;
        entry["network"]["colors"] = network.colors;
        entry["network"]["pastor"] = network.pastor;
        // get campuses in the network
        let campusIds = await strapi.entityService
            .findMany("api::campus.campus", {
            filters: {
                network: {
                    id: {
                        $eq: id,
                    },
                },
            },
        })
            .then((campus) => campus.map((campus) => campus.id));
        let attendancesPromises = [];
        //for the entire year find the attendances for every month
        year.forEach((month) => {
            let attendance = strapi.entityService.findMany("api::services-tracker-form.services-tracker-form", {
                filters: {
                    date: {
                        $lte: month.endDate,
                        $gte: month.startDate,
                    },
                    campus: {
                        id: {
                            $in: campusIds,
                        },
                    },
                },
            });
            attendancesPromises.push(attendance);
        });
        let awaitesAttendances = await Promise.all(attendancesPromises);
        let processedAttendances = [];
        // aggregate the total attendance
        for (let index = 0; index < awaitesAttendances.length; index++) {
            const element = awaitesAttendances[index];
            processedAttendances.push({
                month: months[index],
                total: element.reduce((acc, curr) => {
                    if (curr.total) {
                        return curr.total + acc;
                    }
                    else {
                        return acc;
                    }
                }, 0),
            });
        }
        entry["attendances"] = {};
        entry["attendances"] = processedAttendances.reverse();
        // members added in the past 30 days
        let membersRegisteredThisMonth = await strapi.db
            .query("api::member.member")
            .count({
            where: {
                createdAt: {
                    $gt: (0, helpers_1.getStartOfMonth)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        });
        // members added in the current attendance 60 days to 30 days ago
        let membersRegisteredPreviousMonth = await strapi.db
            .query("api::member.member")
            .count({
            where: {
                createdAt: {
                    $gt: (0, helpers_1.getStartOfPreviousMonth)(),
                    $lt: (0, helpers_1.getStartOfMonth)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        });
        // members count  and trend
        let memberCount = await strapi.entityService.count("api::member.member", {
            filters: {
                network: {
                    id: {
                        $eq: id,
                    },
                },
            },
        });
        let membershipTrend = getPercentage(membersRegisteredThisMonth, memberCount);
        entry["members"] = {};
        entry["members"]["thisMonth"] = membersRegisteredThisMonth;
        entry["members"]["lastMonth"] = membersRegisteredPreviousMonth;
        entry["members"]["trend"] = membershipTrend;
        entry["members"]["total"] = memberCount;
        let staff = await strapi.entityService.count("api::member.member", {
            filters: {
                $and: [
                    {
                        network: {
                            id: {
                                $eq: id,
                            },
                        },
                    },
                    {
                        isStaff: {
                            $eq: true,
                        },
                    },
                    {
                        staffRole: {
                            $notNull: true,
                        },
                    },
                ],
            },
        });
        let staffAddedThisMonth = await strapi.entityService.count("api::member.member", {
            filters: {
                createdAt: {
                    $gt: (0, helpers_1.getStartOfMonth)(),
                },
                network: {
                    id: {
                        $eq: id,
                    },
                },
                isStaff: {
                    $eq: true,
                },
                staffRole: {
                    $notNull: true,
                },
            },
        });
        let staffTrend = getPercentage(staffAddedThisMonth, staff);
        entry["staff"] = {
            total: staff,
            trend: staffTrend,
            thisMonth: staffAddedThisMonth,
        };
        // get total contributions in the month
        let givingThisMonth = await strapi.db
            .query("api::mavuno-giving.mavuno-giving")
            .findMany({
            where: {
                date: {
                    $gt: (0, helpers_1.getStartOfMonth)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        })
            .then((values) => values.reduce((acc, curr) => acc + curr.total, 0));
        let givingLastMonth = await strapi.db
            .query("api::mavuno-giving.mavuno-giving")
            .findMany({
            where: {
                date: {
                    $gt: (0, helpers_1.getStartOfPreviousMonth)(),
                    $lt: (0, helpers_1.getStartOfMonth)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        })
            .then((values) => values.reduce((acc, curr) => acc + curr.total, 0));
        let givingThisWeek = await strapi.entityService
            .findMany("api::mavuno-giving.mavuno-giving", {
            filters: {
                date: {
                    $gt: (0, helpers_1.getStartOfWeek)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        })
            .then((values) => values.reduce((acc, curr) => acc + curr.total, 0));
        let givingToday = await strapi.entityService
            .findMany("api::mavuno-giving.mavuno-giving", {
            filters: {
                date: {
                    $gt: (0, helpers_1.getMidnightToday)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        })
            .then((values) => values.reduce((acc, curr) => acc + curr.total, 0));
        entry["campuses"] = {};
        entry["campuses"]["total"] = campusIds.length;
        entry["giving"] = {};
        entry["giving"]["thisMonth"] = givingThisMonth;
        entry["giving"]["lastMonth"] = givingLastMonth;
        entry["giving"]["today"] = givingToday;
        entry["giving"]["thisWeek"] = givingThisWeek;
        entry["giving"]["trend"] = getTrend(givingThisMonth, givingLastMonth);
        // entry["giving"]["frac"] = ((givingThisMonth - givingLastMonth) / givingLastMonth) ;
        let expenseThisMonth = await strapi.entityService
            .findMany("api::expense.expense", {
            filters: {
                date: {
                    $gt: (0, helpers_1.getStartOfMonth)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        })
            .then((values) => values.reduce((acc, curr) => acc + curr.amount, 0));
        let allocationThisMonth = await strapi.entityService
            .findMany("api::money-allocation.money-allocation", {
            filters: {
                date: {
                    $gt: (0, helpers_1.getStartOfMonth)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        })
            .then((values) => values.reduce((acc, curr) => acc + curr.amount, 0));
        let expenseLastMonth = await strapi.entityService
            .findMany("api::expense.expense", {
            filters: {
                date: {
                    $gt: (0, helpers_1.getStartOfPreviousMonth)(),
                    $lt: (0, helpers_1.getStartOfMonth)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        })
            .then((values) => values.reduce((acc, curr) => acc + curr.amount, 0));
        let allocationLastMonth = await strapi.entityService
            .findMany("api::money-allocation.money-allocation", {
            filters: {
                date: {
                    $gt: (0, helpers_1.getStartOfPreviousMonth)(),
                    $lt: (0, helpers_1.getStartOfMonth)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        })
            .then((values) => values.reduce((acc, curr) => acc + curr.amount, 0));
        entry["expenses"] = {};
        entry["expenses"]["thisMonth"] = expenseThisMonth;
        entry["expenses"]["lastMonth"] = expenseLastMonth;
        entry["expenses"]["trend"] = getTrend(expenseThisMonth, expenseLastMonth);
        entry["expenses"]["percentageOfAllocation"] = getPercentage(expenseThisMonth, allocationThisMonth);
        entry["allocation"] = {};
        entry["allocation"]["thisMonth"] = allocationThisMonth;
        entry["allocation"]["lastMonth"] = allocationLastMonth;
        entry["allocation"]["trend"] = getTrend(allocationThisMonth, allocationLastMonth);
        let expenseThisWeek = await strapi.entityService
            .findMany("api::expense.expense", {
            filters: {
                date: {
                    $gt: (0, helpers_1.getStartOfWeek)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        })
            .then((values) => values.reduce((acc, curr) => acc + curr.amount, 0));
        let expensesToday = await strapi.entityService
            .findMany("api::expense.expense", {
            filters: {
                date: {
                    $gt: (0, helpers_1.getMidnightToday)(),
                },
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        })
            .then((values) => values.reduce((acc, curr) => acc + curr.amount, 0));
        entry["expenses"]["today"] = expensesToday;
        entry["expenses"]["thisWeek"] = expenseThisWeek;
        // let dgs = [];
        // campuses.forEach((it, idx) => {
        //   let dg = strapi.db
        //     .query("api::discipleship-group.discipleship-group")
        //     .findMany({
        //       populate: true,
        //       where: {
        //         campus: {
        //           id: {
        //             $eq: it.id,
        //           },
        //         },
        //       },
        //     });
        //   dgs.push(dg);
        // });
        let discipleshipGroups = await strapi.entityService.count("api::discipleship-group.discipleship-group", {
            filters: {
                campus: {
                    id: {
                        $in: campusIds,
                    },
                },
            },
        });
        entry["discipleshipGroups"] = discipleshipGroups;
    }
    return entry;
}
async function campusSummary(strapi, id) {
    let campus = await strapi.entityService.findOne("api::campus.campus", id, {
        populate: "pastor",
    });
    let allmembers = await strapi.entityService.count("api::member.member", {
        filters: {
            campus: {
                id: {
                    $eq: id,
                },
            },
        },
    });
    let newMembersThisMonth = await strapi.entityService.count("api::member.member", {
        filters: {
            campus: {
                id: {
                    $eq: id,
                },
            },
            createdAt: {
                $gt: (0, helpers_1.getStartOfMonth)(),
            },
        },
    });
    let newMembersLastMonth = await strapi.entityService.count("api::member.member", {
        filters: {
            campus: {
                id: {
                    $eq: id,
                },
            },
            createdAt: {
                $gt: (0, helpers_1.getStartOfPreviousMonth)(),
                $lt: (0, helpers_1.getStartOfMonth)(),
            },
        },
    });
    let memberTrend = getPercentage(newMembersThisMonth, newMembersLastMonth);
    let members = {
        thisMonth: newMembersThisMonth,
        lastMonth: newMembersLastMonth,
        trend: memberTrend,
        count: allmembers,
    };
    let staffAddedThisMonth = await strapi.entityService.count("api::member.member", {
        filters: {
            campus: {
                id: {
                    $eq: id,
                },
            },
            createdAt: {
                $gt: (0, helpers_1.getStartOfMonth)(),
            },
            isStaff: {
                $eq: true,
            },
            staffRole: {
                $notNull: true,
            },
        },
    });
    let staffTotal = await strapi.entityService.count("api::member.member", {
        filters: {
            campus: {
                id: {
                    $eq: id,
                },
            },
            isStaff: {
                $eq: true,
            },
            staffRole: {
                $notNull: true,
            },
        },
    });
    let staffTrend = getPercentage(staffAddedThisMonth, staffTotal);
    let givingToday = await strapi.entityService
        .findMany("api::mavuno-giving.mavuno-giving", {
        filters: {
            date: {
                $gt: (0, helpers_1.getMidnightToday)(),
            },
            campus: {
                id: {
                    $eq: id,
                },
            },
        },
    })
        .then((values) => values.reduce((acc, curr) => acc + curr.total, 0));
    let givingThisWeek = await strapi.entityService
        .findMany("api::mavuno-giving.mavuno-giving", {
        filters: {
            date: {
                $gt: (0, helpers_1.getStartOfWeek)(),
            },
            campus: {
                id: {
                    $eq: id,
                },
            },
        },
    })
        .then((values) => values.reduce((acc, curr) => acc + curr.total, 0));
    let givingThisMonth = await strapi.entityService
        .findMany("api::mavuno-giving.mavuno-giving", {
        filters: {
            date: {
                $gt: (0, helpers_1.getStartOfMonth)(),
            },
            campus: {
                id: {
                    $eq: id,
                },
            },
        },
    })
        .then((values) => values.reduce((acc, curr) => acc + curr.total, 0));
    let givingLastMonth = await strapi.entityService
        .findMany("api::mavuno-giving.mavuno-giving", {
        filters: {
            date: {
                $gt: (0, helpers_1.getStartOfPreviousMonth)(),
                $lt: (0, helpers_1.getStartOfMonth)(),
            },
            campus: {
                id: {
                    $eq: id,
                },
            },
        },
    })
        .then((values) => values.reduce((acc, curr) => acc + curr.total, 0));
    let grivingTrend = getTrend(givingThisMonth, givingLastMonth);
    let giving = {
        thisMonth: givingThisMonth,
        lastMonth: givingLastMonth,
        today: givingToday,
        thisWeek: givingThisWeek,
        trend: grivingTrend,
    };
    let expensesToday = await strapi.entityService
        .findMany("api::expense.expense", {
        filters: {
            date: {
                $gt: (0, helpers_1.getMidnightToday)(),
            },
            campus: {
                id: {
                    $eq: id,
                },
            },
        },
    })
        .then((values) => values.reduce((acc, curr) => acc + curr.amount, 0));
    let expensesThisWeek = await strapi.entityService
        .findMany("api::expense.expense", {
        filters: {
            date: {
                $gt: (0, helpers_1.getStartOfWeek)(),
            },
            campus: {
                id: {
                    $eq: id,
                },
            },
        },
    })
        .then((values) => values.reduce((acc, curr) => acc + curr.amount, 0));
    let expensesThisMonth = await strapi.entityService
        .findMany("api::expense.expense", {
        filters: {
            date: {
                $gt: (0, helpers_1.getStartOfMonth)(),
            },
            campus: {
                id: {
                    $eq: id,
                },
            },
        },
    })
        .then((values) => values.reduce((acc, curr) => acc + curr.amount, 0));
    let expensesLastMonth = await strapi.entityService
        .findMany("api::expense.expense", {
        filters: {
            date: {
                $gt: (0, helpers_1.getStartOfPreviousMonth)(),
                $lt: (0, helpers_1.getStartOfMonth)(),
            },
            campus: {
                id: {
                    $eq: id,
                },
            },
        },
    })
        .then((values) => values.reduce((acc, curr) => acc + curr.amount, 0));
    let expenses = {
        thisMonth: expensesThisMonth,
        lastMonth: expensesLastMonth,
        today: expensesToday,
        thisWeek: expensesThisWeek,
        trend: getTrend(expensesThisMonth, expensesLastMonth),
    };
    let yearInformation = (0, helpers_1.getYearMonthsFromToday)();
    let attendances = [];
    for (let index = 0; index < yearInformation.length; index++) {
        const element = yearInformation[index];
        let attendancesInMonth = await strapi.entityService.findMany("api::services-tracker-form.services-tracker-form", {
            filters: {
                date: {
                    $gt: element.startDate,
                    $lt: element.endDate,
                },
                campus: {
                    id: {
                        $eq: id,
                    },
                },
            },
        });
        let mothValue = {
            month: element.name,
            total: attendancesInMonth.reduce((acc, curr) => {
                if (curr.total) {
                    return curr.total + acc;
                }
                else {
                    return acc;
                }
            }, 0),
        };
        attendances.push(mothValue);
    }
    let discipleshipGroups = await strapi.entityService.count("api::discipleship-group.discipleship-group", {
        filters: {
            campus: {
                id: {
                    $eq: id,
                },
            },
        },
    });
    return {
        campus,
        members: members,
        staff: {
            total: staffTotal,
            trend: staffTrend,
            thisMonth: staffAddedThisMonth,
        },
        expenses: expenses,
        givings: giving,
        discipleshipGroups: discipleshipGroups,
        attendances: attendances.reverse(),
    };
}
function getTrend(current, previous) {
    let divisor = previous == 0 ? 1 : previous;
    return parseFloat(((current - previous) / divisor).toFixed(2)) * 100;
}
exports.getTrend = getTrend;
function sumAllValues(data) {
    const result = {
        attendances: [],
        members: {
            thisMonth: 0,
            lastMonth: 0,
            trend: 0,
            total: 0,
        },
        staff: {
            total: 0,
            trend: 0,
            thisMonth: 0,
        },
        campuses: {
            total: 0,
        },
        expenses: {
            thisMonth: 0,
            lastMonth: 0,
            percentageOfAllocation: 0,
            trend: 0,
            today: 0,
            thisWeek: 0,
        },
        giving: {
            thisMonth: 0,
            lastMonth: 0,
            today: 0,
            thisWeek: 0,
            trend: 0,
        },
        allocation: {
            thisMonth: 0,
            lastMonth: 0,
            trend: 0,
        },
        discipleshipGroups: 0,
    };
    for (let i = 0; i < data.length; i++) {
        const entry = data[i];
        // Sum total attendance without reducing
        result.attendances.push(entry.attendances);
        result.staff.thisMonth += entry.staff.thisMonth;
        result.staff.trend += entry.staff.trend;
        result.staff.total += entry.staff.total;
        result.expenses.percentageOfAllocation +=
            entry.expenses.percentageOfAllocation;
        result.allocation.thisMonth += entry.allocation.thisMonth;
        result.allocation.lastMonth += entry.allocation.lastMonth;
        result.allocation.trend += entry.allocation.trend;
        // Sum members data
        result.members.thisMonth += entry.members.thisMonth;
        result.members.lastMonth += entry.members.lastMonth;
        result.members.trend += entry.members.trend;
        result.members.total += entry.members.total;
        // Sum campuses data
        result.campuses.total += entry.campuses.total;
        // Sum giving data
        result.giving.thisMonth += entry.giving.thisMonth;
        result.giving.lastMonth += entry.giving.lastMonth;
        result.giving.trend += entry.giving.trend;
        result.giving.today += entry.giving.today;
        result.giving.lastMonth += entry.giving.lastMonth;
        result.expenses.thisMonth += entry.expenses.thisMonth;
        result.expenses.thisWeek += entry.expenses.thisMonth;
        result.expenses.today += entry.expenses.today;
        result.expenses.lastMonth += entry.expenses.lastMonth;
        result.expenses.trend += entry.expenses.trend;
        // Sum discipleshipGroups data
        result.discipleshipGroups += entry.discipleshipGroups;
    }
    // Calculate average trend
    result.expenses.trend = getTrend(result.expenses.thisMonth, result.expenses.lastMonth);
    result.members.trend = getPercentage(result.members.thisMonth, result.members.total);
    result.staff.trend = getPercentage(result.staff.thisMonth, result.staff.total);
    result.giving.trend = getTrend(result.giving.thisMonth, result.giving.lastMonth);
    result.expenses.percentageOfAllocation = getPercentage(result.expenses.thisMonth, result.allocation.thisMonth);
    result.attendances = sumNestedArrays(result.attendances).reverse();
    return result;
}
function sumNestedArrays(nestedArrays) {
    const result = [];
    // Initialize a map to store totals for each month
    const monthTotals = new Map();
    // Iterate through each array in the nested arrays
    for (let i = 0; i < nestedArrays.length; i++) {
        const currentArray = nestedArrays[i];
        // Iterate through each object in the current array
        for (let j = 0; j < currentArray.length; j++) {
            const currentObject = currentArray[j];
            // If the month is already in the map, add the totals
            if (monthTotals.has(currentObject.month)) {
                monthTotals.set(currentObject.month, monthTotals.get(currentObject.month) + currentObject.total);
            }
            else {
                // If the month is not in the map, initialize it
                monthTotals.set(currentObject.month, currentObject.total);
            }
        }
    }
    // Convert the map back to an array of objects
    monthTotals.forEach((totals, month) => {
        result.push({
            month: month,
            total: totals,
        });
    });
    return result.reverse();
}
function getPercentage(number1, number2) {
    if (number2 === 0) {
        return 0;
    }
    else {
        return (number1 / number2) * 100;
    }
}
