"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MembersHelper = void 0;
const common_1 = require("@nestjs/common");
const utils_1 = require("../../utils");
let MembersHelper = class MembersHelper {
    normalizeDate(value) {
        return new Date(Date.UTC(value.getFullYear(), value.getMonth(), value.getDate()));
    }
    startOfYear(value) {
        return new Date(Date.UTC(value.getUTCFullYear(), 0, 1));
    }
    parseWorkingDays(workingDays) {
        if (!Array.isArray(workingDays)) {
            throw (0, utils_1.createGeneralError)('Working schedule is invalid for this owner', 'working_days', common_1.HttpStatus.BAD_REQUEST);
        }
        const dayNameToIndex = {
            sunday: 0,
            monday: 1,
            tuesday: 2,
            wednesday: 3,
            thursday: 4,
            friday: 5,
            saturday: 6,
        };
        const parsed = new Set();
        for (const day of workingDays) {
            if (typeof day !== 'string') {
                continue;
            }
            const normalized = day.trim().toLowerCase();
            const index = dayNameToIndex[normalized];
            if (typeof index === 'number') {
                parsed.add(index);
            }
        }
        if (parsed.size === 0) {
            throw (0, utils_1.createGeneralError)('Working days must include at least one valid day', 'working_days', common_1.HttpStatus.BAD_REQUEST);
        }
        return parsed;
    }
    calculateAssignedLeaveDays(policy) {
        if (!policy) {
            return 0;
        }
        return (policy.annual_leave_days +
            policy.sick_leave_days +
            policy.casual_leave_days +
            policy.maternity_leave_days +
            policy.paternity_leave_days +
            policy.personal_leave_days +
            policy.compensatory_leave_days);
    }
    isLeapYear(year) {
        return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);
    }
    buildRecurringOccurrence(baseDate, year) {
        const month = baseDate.getUTCMonth();
        const day = baseDate.getUTCDate();
        if (month === 1 && day === 29 && !this.isLeapYear(year)) {
            return null;
        }
        const occurrence = new Date(Date.UTC(year, month, day));
        if (occurrence.getUTCMonth() !== month || occurrence.getUTCDate() !== day) {
            return null;
        }
        return occurrence;
    }
    addDays(value, days) {
        const next = new Date(value);
        next.setUTCDate(next.getUTCDate() + days);
        return next;
    }
    getRangeLength(startDate, endDate) {
        return Math.max(0, Math.round((this.normalizeDate(endDate).getTime() -
            this.normalizeDate(startDate).getTime()) /
            (1000 * 60 * 60 * 24)));
    }
    buildRecurringRange(startDate, endDate, year) {
        const occurrenceStart = this.buildRecurringOccurrence(startDate, year);
        if (!occurrenceStart) {
            return null;
        }
        const occurrenceEnd = this.addDays(occurrenceStart, this.getRangeLength(startDate, endDate));
        return { occurrenceStart, occurrenceEnd };
    }
    buildHolidayDateSet(from, to, holidays) {
        const dates = new Set();
        for (const holiday of holidays) {
            const holidayStart = this.normalizeDate(holiday.start_date);
            const holidayEnd = this.normalizeDate(holiday.end_date);
            if (holiday.is_recurring) {
                const startYear = Math.max(from.getUTCFullYear(), holidayStart.getUTCFullYear());
                for (let year = startYear; year <= to.getUTCFullYear(); year += 1) {
                    const occurrence = this.buildRecurringRange(holidayStart, holidayEnd, year);
                    if (!occurrence) {
                        continue;
                    }
                    if (occurrence.occurrenceEnd < from ||
                        occurrence.occurrenceStart > to) {
                        continue;
                    }
                    const current = new Date(occurrence.occurrenceStart);
                    while (current <= occurrence.occurrenceEnd) {
                        if (current >= from && current <= to) {
                            dates.add(this.normalizeDate(current).toISOString());
                        }
                        current.setUTCDate(current.getUTCDate() + 1);
                    }
                }
                continue;
            }
            const current = new Date(holidayStart);
            while (current <= holidayEnd) {
                if (current >= from && current <= to) {
                    dates.add(this.normalizeDate(current).toISOString());
                }
                current.setUTCDate(current.getUTCDate() + 1);
            }
        }
        return dates;
    }
    countWorkingDays(from, to, holidayDates, workingDayIndexes) {
        const current = new Date(from);
        let count = 0;
        while (current <= to) {
            const normalized = this.normalizeDate(current).toISOString();
            const dayIndex = current.getUTCDay();
            if (workingDayIndexes.has(dayIndex) && !holidayDates.has(normalized)) {
                count += 1;
            }
            current.setUTCDate(current.getUTCDate() + 1);
        }
        return count;
    }
    countLeaveDays(from, to, leaves) {
        return leaves.reduce((total, leave) => {
            const leaveStart = this.normalizeDate(leave.start_date);
            const leaveEnd = this.normalizeDate(leave.end_date ?? leave.start_date);
            const overlapStart = leaveStart > from ? leaveStart : from;
            const overlapEnd = leaveEnd < to ? leaveEnd : to;
            if (overlapStart > overlapEnd) {
                return total;
            }
            const dayCount = Math.floor((overlapEnd.getTime() - overlapStart.getTime()) /
                (1000 * 60 * 60 * 24)) + 1;
            return total + dayCount;
        }, 0);
    }
    buildResponse(data, total, page, limit) {
        const totalPages = Math.ceil(total / limit);
        return {
            data,
            message: 'Members filtered successfully',
            status: common_1.HttpStatus.OK,
            details: {
                pagination: {
                    total_items: total,
                    total_pages: totalPages,
                    current_page: page,
                    items_per_page: limit,
                    has_next_page: page < totalPages,
                    has_previous_page: page > 1,
                    next_page: page < totalPages ? page + 1 : null,
                    previous_page: page > 1 ? page - 1 : null,
                },
            },
        };
    }
};
exports.MembersHelper = MembersHelper;
exports.MembersHelper = MembersHelper = __decorate([
    (0, common_1.Injectable)()
], MembersHelper);
//# sourceMappingURL=members.helper.js.map