namespace TaxBaik.Application.Utils;

public static class BusinessDayCalculator
{
    private static readonly HashSet<DateOnly> HolidayDates = new()
    {
        // 2026
        new DateOnly(2026, 1, 1),
        new DateOnly(2026, 2, 16),
        new DateOnly(2026, 2, 17),
        new DateOnly(2026, 2, 18),
        new DateOnly(2026, 3, 1),
        new DateOnly(2026, 3, 2),
        new DateOnly(2026, 5, 5),
        new DateOnly(2026, 5, 25),
        new DateOnly(2026, 6, 6),
        new DateOnly(2026, 8, 15),
        new DateOnly(2026, 8, 16),
        new DateOnly(2026, 8, 17),
        new DateOnly(2026, 9, 24),
        new DateOnly(2026, 9, 25),
        new DateOnly(2026, 9, 26),
        new DateOnly(2026, 10, 3),
        new DateOnly(2026, 10, 4),
        new DateOnly(2026, 10, 5),
        new DateOnly(2026, 10, 9),
        new DateOnly(2026, 12, 25),

        // 2027
        new DateOnly(2027, 1, 1),
        new DateOnly(2027, 2, 6),
        new DateOnly(2027, 2, 7),
        new DateOnly(2027, 2, 8),
        new DateOnly(2027, 2, 9),
        new DateOnly(2027, 3, 1),
        new DateOnly(2027, 3, 2),
        new DateOnly(2027, 5, 5),
        new DateOnly(2027, 5, 13),
        new DateOnly(2027, 6, 6),
        new DateOnly(2027, 8, 15),
        new DateOnly(2027, 8, 16),
        new DateOnly(2027, 9, 14),
        new DateOnly(2027, 9, 15),
        new DateOnly(2027, 9, 16),
        new DateOnly(2027, 10, 3),
        new DateOnly(2027, 10, 4),
        new DateOnly(2027, 10, 9),
        new DateOnly(2027, 10, 10),
        new DateOnly(2027, 10, 11),
        new DateOnly(2027, 12, 25),
        new DateOnly(2027, 12, 26)
    };

    public static DateOnly GetEffectiveDueDate(DateOnly dueDate)
    {
        var effectiveDate = dueDate;
        while (!IsBusinessDay(effectiveDate))
        {
            effectiveDate = effectiveDate.AddDays(1);
        }

        return effectiveDate;
    }

    public static int GetDday(DateOnly dueDate, DateOnly? referenceDate = null)
    {
        var today = referenceDate ?? DateOnly.FromDateTime(DateTime.Today);
        var effectiveDueDate = GetEffectiveDueDate(dueDate);
        return effectiveDueDate.DayNumber - today.DayNumber;
    }

    public static bool IsBusinessDay(DateOnly date)
        => date.DayOfWeek is not DayOfWeek.Saturday and not DayOfWeek.Sunday
           && !HolidayDates.Contains(date);
}
