<?php

namespace App\Utilities;

use Carbon\Carbon;
use Carbon\CarbonPeriod;

class WorkingDaysCalculator
{
    public const TIMEZONE = 'America/New_York';

    public static function calculate(string $month, array $holidays = []): int
    {
        $start = Carbon::createFromFormat('Y-m', $month, self::TIMEZONE)->startOfMonth();
        $end = $start->copy()->endOfMonth();

        return self::getWorkingDaysInRange($start->toDateString(), $end->toDateString(), $holidays);
    }

    public static function getWorkingDaysInRange(string $start, string $end, array $holidays = []): int
    {
        $period = CarbonPeriod::create(
            Carbon::create($start, self::TIMEZONE),
            Carbon::create($end, self::TIMEZONE)
        );
        $holidayLookup = array_flip($holidays);
        $workingDays = 0;

        foreach ($period as $day) {
            $date = $day->toDateString();

            if (self::isWorkingDay($date, $holidayLookup)) {
                $workingDays++;
            }
        }

        return $workingDays;
    }

    public static function isWorkingDay(string $date, array $holidays = []): bool
    {
        $carbonDate = Carbon::create($date, self::TIMEZONE);

        if ($carbonDate->isWeekend()) {
            return false;
        }

        if (isset($holidays[$carbonDate->toDateString()])) {
            return false;
        }

        return true;
    }

    public static function isWeekend(string $date): bool
    {
        return Carbon::create($date, self::TIMEZONE)->isWeekend();
    }
}
