<?php

declare(strict_types=1);

namespace App\Service\Utils;

use DateTime;

/**
 * Class Dates : méthodes d'aide pour la gestion de dates.
 */
class DatesUtils
{
    // For testing purpose, see setFakeDatetime and clearFakeDatetime method
    protected static ?string $fakeDateTime = null;

    /**
     * @throws \Exception
     */
    public static function new(string $datetime = 'now', ?\DateTimeZone $timezone = null): \DateTime
    {
        if ($datetime === 'now') {
            $datetime = static::$fakeDateTime ?? $datetime;
        }

        return new \DateTime($datetime, $timezone);
    }

    /**
     * Set a fake datetime string that will be use in the 'new' method instead of whenever
     * the passed datetime is 'now'.
     */
    public static function setFakeDatetime(string $datetime): void
    {
        self::$fakeDateTime = $datetime;
    }

    public static function clearFakeDatetime(): void
    {
        self::$fakeDateTime = null;
    }

    /**
     * Vérifie si la date du jour est comprise dans l'interval passé en paramètres.
     *
     * @see DatesUtilsTest::testIsNowInInterval()
     */
    public static function isNowInInterval(\DateTimeInterface $dateStart, ?\DateTimeInterface $dateEnd = null): bool
    {
        $now = self::new();

        return $dateStart <= $now && (is_null($dateEnd) || $dateEnd >= $now);
    }

    /**
     * Retourne le nombre de jours écoulés depuis la date passée en paramètre.
     *
     * @throws \Exception
     */
    public static function daysSince(\DateTimeInterface $dateTime): int
    {
        return (int) self::new()
            ->diff($dateTime)
            ->format('%a');
    }
}
