<?php

declare(strict_types=1);

namespace App\Tests\Service\WorkHours;

use App\Entity\WorkHour;
use App\Service\WorkHours\NightHoursCalculator;
use DateTimeImmutable;
use PHPUnit\Framework\TestCase;

/**
 * @internal
 */
final class NightHoursCalculatorTest extends TestCase
{
    public function testNullRangeReturnsZero(): void
    {
        $calc = new NightHoursCalculator();
        self::assertSame(0, $calc->nightIntervalMinutes(null, null));
        self::assertSame(0, $calc->nightIntervalMinutes('08:00', null));
        self::assertSame(0, $calc->nightIntervalMinutes(null, '17:00'));
    }

    public function testPureDayRangeHasNoNight(): void
    {
        $calc = new NightHoursCalculator();
        // 08:00 -> 17:00 : entierement hors fenetres nuit (00:00-06:00, 21:00-24:00).
        self::assertSame(0, $calc->nightIntervalMinutes('08:00', '17:00'));
    }

    public function testWindowBoundariesAreRightExclusive(): void
    {
        $calc = new NightHoursCalculator();
        // 06:00 -> 21:00 : pile entre les deux fenetres de nuit, 0 min.
        self::assertSame(0, $calc->nightIntervalMinutes('06:00', '21:00'));
        // 22:00 -> 06:00 : 22-24 (120) + 00-06 (360) = 480, borne 06:00 exclue.
        self::assertSame(480, $calc->nightIntervalMinutes('22:00', '06:00'));
    }

    public function testEveningWindowCounts(): void
    {
        $calc = new NightHoursCalculator();
        // 21:00 -> 24:00 = 180 min de nuit.
        self::assertSame(180, $calc->nightIntervalMinutes('21:00', '00:00'));
    }

    public function testShiftCrossingMidnightCountsBothWindows(): void
    {
        $calc = new NightHoursCalculator();
        // 21:00 -> 05:00 : 21-24 (180) + 00-05 (300) = 480 min.
        self::assertSame(480, $calc->nightIntervalMinutes('21:00', '05:00'));
    }

    public function testNightMinutesForWorkHourDriverUsesManualField(): void
    {
        $calc = new NightHoursCalculator();
        $wh   = new WorkHour();
        $wh->setWorkDate(new DateTimeImmutable('2026-01-15'))
            ->setDayHoursMinutes(300)
            ->setNightHoursMinutes(250)
            ->setMorningFrom('08:00')->setMorningTo('12:00')
        ;

        // Driver -> champ manuel nightHoursMinutes, plages ignorees.
        self::assertSame(250, $calc->nightMinutesForWorkHour($wh, true));
    }

    public function testNightMinutesForWorkHourNonDriverSumsRanges(): void
    {
        $calc = new NightHoursCalculator();
        $wh   = new WorkHour();
        $wh->setWorkDate(new DateTimeImmutable('2026-01-15'))
            ->setMorningFrom('22:00')->setMorningTo('00:00')   // 120 min nuit
            ->setEveningFrom('04:00')->setEveningTo('06:00')  // 120 min nuit
        ;

        self::assertSame(240, $calc->nightMinutesForWorkHour($wh, false));
    }
}
