"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getIsTodayWeekend = exports.getCurrentWeekDetails = exports.getDaysBetweenInBd = exports.getAttendanceDetailsCountFromStartAndEnd = exports.getAttendanceCountFromStartAndEnd = exports.getTotalWorkingDayFromStartAndEnd = exports.getLeaveCountFromStartAndEnd = exports.countHolidayFromStartAndEnd = void 0;
const date_fns_1 = require("date-fns");
const date_fns_tz_1 = require("date-fns-tz");
const timezone_util_1 = require("../common/timezone/timezone.util");
const timezone_constants_1 = require("../common/timezone/timezone.constants");
const attendance_summary_util_1 = require("./attendance-summary.util");
const resolveScheduleTimezone = (workSchedule) => (0, timezone_util_1.normalizeTimezone)(workSchedule?.timezone);
const countHolidayFromStartAndEnd = (holidays, workSchedule, start, end) => {
    const timeZone = resolveScheduleTimezone(workSchedule);
    const holidayDays = new Set();
    const workingDays = workSchedule.working_days.map((day) => day.toLowerCase());
    for (const holiday of holidays) {
        const holidayStart = new Date(holiday.start_date);
        const holidayEnd = new Date(holiday.end_date);
        if (holidayEnd < start || holidayStart > end) {
            continue;
        }
        const rangeStart = holidayStart > start ? holidayStart : start;
        const rangeEnd = holidayEnd < end ? holidayEnd : end;
        const days = (0, date_fns_1.eachDayOfInterval)({
            start: rangeStart,
            end: rangeEnd,
        });
        for (const day of days) {
            const bdDate = (0, date_fns_tz_1.formatInTimeZone)(day, timeZone, 'yyyy-MM-dd');
            const bdDayName = (0, date_fns_tz_1.formatInTimeZone)(day, timeZone, 'EEEE').toLowerCase();
            if (!workingDays.includes(bdDayName)) {
                continue;
            }
            holidayDays.add(bdDate);
        }
    }
    return holidayDays.size;
};
exports.countHolidayFromStartAndEnd = countHolidayFromStartAndEnd;
const getLeaveCountFromStartAndEnd = (leaves, workSchedule, start, end, checkWorkSchedule = true) => {
    const timeZone = resolveScheduleTimezone(workSchedule);
    const leaveDays = new Set();
    const workingDays = workSchedule.working_days.map((day) => day.toLowerCase());
    for (const leave of leaves) {
        const leaveStart = new Date(leave.start_date);
        let leaveEnd = new Date(leave.end_date);
        if (leaveEnd.getUTCHours() === 0 &&
            leaveEnd.getUTCMinutes() === 0 &&
            leaveEnd.getUTCSeconds() === 0 &&
            leaveEnd.getUTCMilliseconds() === 0) {
            leaveEnd = new Date(leaveEnd.getTime() - 1);
        }
        if (leaveEnd < start || leaveStart > end)
            continue;
        const rangeStart = leaveStart > start ? leaveStart : start;
        const rangeEnd = leaveEnd < end ? leaveEnd : end;
        const startBdStr = (0, date_fns_tz_1.formatInTimeZone)(rangeStart, timeZone, 'yyyy-MM-dd');
        const endBdStr = (0, date_fns_tz_1.formatInTimeZone)(rangeEnd, timeZone, 'yyyy-MM-dd');
        const current = new Date(startBdStr);
        const endDate = new Date(endBdStr);
        while (current <= endDate) {
            const bdDate = (0, date_fns_1.format)(current, 'yyyy-MM-dd');
            const bdDayName = (0, date_fns_1.format)(current, 'EEEE').toLowerCase();
            if (!checkWorkSchedule || workingDays.includes(bdDayName)) {
                leaveDays.add(bdDate);
            }
            current.setDate(current.getDate() + 1);
        }
    }
    return leaveDays.size;
};
exports.getLeaveCountFromStartAndEnd = getLeaveCountFromStartAndEnd;
const getTotalWorkingDayFromStartAndEnd = (holidays, workSchedule, start, end) => {
    const timeZone = resolveScheduleTimezone(workSchedule);
    console.log('Calculating total working days from', start, 'to', end);
    const holidayDays = new Set();
    const workingDays = workSchedule.working_days.map((day) => day.toLowerCase());
    const zonedStart = (0, date_fns_tz_1.toZonedTime)(start, timeZone);
    const zonedEnd = (0, date_fns_tz_1.toZonedTime)(end, timeZone);
    for (const holiday of holidays) {
        const holidayStart = (0, date_fns_tz_1.toZonedTime)(new Date(holiday.start_date), timeZone);
        const holidayEnd = (0, date_fns_tz_1.toZonedTime)(new Date(holiday.end_date), timeZone);
        if (holidayEnd < zonedStart || holidayStart > zonedEnd) {
            continue;
        }
        const rangeStart = holidayStart > zonedStart ? holidayStart : zonedStart;
        const rangeEnd = holidayEnd < zonedEnd ? holidayEnd : zonedEnd;
        const holidayRangeDays = (0, date_fns_1.eachDayOfInterval)({
            start: rangeStart,
            end: rangeEnd,
        });
        for (const day of holidayRangeDays) {
            const bdDate = (0, date_fns_tz_1.formatInTimeZone)(day, timeZone, 'yyyy-MM-dd');
            const bdDayName = (0, date_fns_tz_1.formatInTimeZone)(day, timeZone, 'EEEE').toLowerCase();
            if (!workingDays.includes(bdDayName)) {
                continue;
            }
            holidayDays.add(bdDate);
        }
    }
    const totalDays = (0, date_fns_1.eachDayOfInterval)({
        start: zonedStart,
        end: zonedEnd,
    });
    let workingDayCount = 0;
    for (const day of totalDays) {
        const bdDate = (0, date_fns_tz_1.formatInTimeZone)(day, timeZone, 'yyyy-MM-dd');
        const bdDayName = (0, date_fns_tz_1.formatInTimeZone)(day, timeZone, 'EEEE').toLowerCase();
        if (!workingDays.includes(bdDayName)) {
            continue;
        }
        if (holidayDays.has(bdDate)) {
            continue;
        }
        workingDayCount++;
    }
    return workingDayCount;
};
exports.getTotalWorkingDayFromStartAndEnd = getTotalWorkingDayFromStartAndEnd;
const getAttendanceCountFromStartAndEnd = (attendances, start, end, currentDate) => {
    let attendanceCount = 0;
    for (const attendance of attendances) {
        const attendanceDate = new Date(attendance.date);
        if (attendanceDate < start || attendanceDate > end) {
            continue;
        }
        const isToday = attendanceDate.toDateString() === currentDate.toDateString();
        if ((0, attendance_summary_util_1.isGroupedPresent)(attendance.status, isToday)) {
            attendanceCount++;
        }
    }
    return attendanceCount;
};
exports.getAttendanceCountFromStartAndEnd = getAttendanceCountFromStartAndEnd;
const getAttendanceDetailsCountFromStartAndEnd = (attendances, start, end, currentDate) => {
    let attendanceCount = 0;
    let lateCount = 0;
    let halfDayCount = 0;
    for (const attendance of attendances) {
        const attendanceDate = new Date(attendance.date);
        if (attendanceDate < start || attendanceDate > end) {
            continue;
        }
        const isToday = attendanceDate.toDateString() === currentDate.toDateString();
        const bucket = (0, attendance_summary_util_1.classifyIndividualSummaryBucket)(attendance.status, isToday);
        if (bucket === 'present') {
            attendanceCount++;
        }
        else if (bucket === 'late') {
            lateCount++;
        }
        else if (bucket === 'half_day') {
            halfDayCount++;
        }
    }
    return {
        attendance_count: attendanceCount,
        late_count: lateCount,
        half_day_count: halfDayCount,
    };
};
exports.getAttendanceDetailsCountFromStartAndEnd = getAttendanceDetailsCountFromStartAndEnd;
const getDaysBetweenInBd = (startUtc, endUtc, timeZone = timezone_constants_1.DEFAULT_ORG_TIMEZONE) => {
    const startBd = (0, date_fns_tz_1.formatInTimeZone)(startUtc, timeZone, 'yyyy-MM-dd');
    const endBd = (0, date_fns_tz_1.formatInTimeZone)(endUtc, timeZone, 'yyyy-MM-dd');
    let current = new Date(`${startBd}T00:00:00`);
    const end = new Date(`${endBd}T00:00:00`);
    const days = [];
    while (current <= end) {
        days.push(new Date(current));
        current = (0, date_fns_1.addDays)(current, 1);
    }
    return days;
};
exports.getDaysBetweenInBd = getDaysBetweenInBd;
const getCurrentWeekDetails = (startUtc, endUtc, holidays, leaves, workSchedule) => {
    const timeZone = resolveScheduleTimezone(workSchedule);
    const weekDetails = (0, exports.getDaysBetweenInBd)(startUtc, endUtc, timeZone).map((day) => {
        const bdDate = (0, date_fns_tz_1.formatInTimeZone)(day, timeZone, 'yyyy-MM-dd');
        const bdDayName = (0, date_fns_tz_1.formatInTimeZone)(day, timeZone, 'EEEE').toLowerCase();
        return {
            label: (0, date_fns_tz_1.formatInTimeZone)(day, timeZone, 'EEE'),
            date: bdDate,
            day: (0, date_fns_tz_1.formatInTimeZone)(day, timeZone, 'dd'),
            is_holiday: holidays.some((holiday) => {
                const holidayStart = (0, date_fns_tz_1.formatInTimeZone)(new Date(holiday.start_date), timeZone, 'yyyy-MM-dd');
                const holidayEnd = (0, date_fns_tz_1.formatInTimeZone)(new Date(holiday.end_date), timeZone, 'yyyy-MM-dd');
                return bdDate >= holidayStart && bdDate <= holidayEnd;
            }),
            is_leave: leaves.some((leave) => {
                const leaveStart = (0, date_fns_tz_1.formatInTimeZone)(new Date(leave.start_date), timeZone, 'yyyy-MM-dd');
                const leaveEnd = (0, date_fns_tz_1.formatInTimeZone)(new Date(leave.end_date), timeZone, 'yyyy-MM-dd');
                return bdDate >= leaveStart && bdDate <= leaveEnd;
            }),
            is_weekend: !workSchedule.working_days.includes(bdDayName),
            is_completed: new Date() > day,
            is_today: (0, date_fns_tz_1.formatInTimeZone)(new Date(), timeZone, 'yyyy-MM-dd') === bdDate,
        };
    });
    return weekDetails;
};
exports.getCurrentWeekDetails = getCurrentWeekDetails;
const getIsTodayWeekend = (holidays, workSchedule, startUtc) => {
    const timeZone = resolveScheduleTimezone(workSchedule);
    const todayBdDayName = (0, date_fns_tz_1.formatInTimeZone)(startUtc, timeZone, 'EEEE').toLowerCase();
    const isHoliday = holidays.some((holiday) => {
        const holidayStart = new Date(holiday.start_date);
        const holidayEnd = new Date(holiday.end_date);
        return startUtc >= holidayStart && startUtc <= holidayEnd;
    });
    const isWeekend = !workSchedule.working_days.includes(todayBdDayName);
    return {
        isHoliday,
        isWeekend,
    };
};
exports.getIsTodayWeekend = getIsTodayWeekend;
//# sourceMappingURL=dashboard.js.map