<?php

declare(strict_types=1);

namespace NoahVet\Reef\Test\A_Unit\Domain\Comparator;

use NoahVet\Reef\Domain\Comparator\DateComparator;
use NoahVet\Reef\Domain\Comparator\DateComparatorInterface;
use PHPUnit\Framework\TestCase;

class DateComparatorTest extends TestCase
{
    private DateComparatorInterface $subject;

    protected function setUp(): void
    {
        $this->subject = new DateComparator();
    }

    public function testEndDateShouldBeTheLastDayOfTheYearWithGoodDates(): void
    {
        $startDate = new \DateTime('2024-01-10T23:40:01+00:00');
        $endDate = new \DateTime('2024-12-31T23:59:59+00:00');

        self::assertTrue(
            $this->subject->endDateShouldBeTheLastDayOfTheYear($startDate, $endDate),
        );
    }

    public function testEndDateShouldBeTheLastDayOfTheYearWithMidnightEndDate(): void
    {
        $startDate = new \DateTime('2024-01-10T21:30:02+00:00');
        $endDate = new \DateTime('2024-12-31T00:00:00+00:00');

        self::assertFalse(
            $this->subject->endDateShouldBeTheLastDayOfTheYear($startDate, $endDate),
        );
    }

    public function testEndDateShouldBeTheLastDayOfTheYearWhenEndDateIsBeforeStartDate(): void
    {
        $startDate = new \DateTime('2024-10-15T10:22:00+00:00');
        $endDate = new \DateTime('2024-09-15T23:59:59+00:00');

        self::assertFalse(
            $this->subject->endDateShouldBeTheLastDayOfTheYear($startDate, $endDate),
        );
    }

    public function testEndDateShouldBeGreaterThanOrEqualsToTheLastDayOfTheYearWithGoodDates(): void
    {
        $startDate = new \DateTime('2024-01-10T23:40:01+00:00');
        $endDate = new \DateTime('2024-12-31T23:59:59+00:00');

        self::assertTrue(
            $this->subject->endDateShouldBeGreaterThanOrEqualsToTheLastDayOfTheYear($startDate, $endDate),
        );
    }

    public function testEndDateShouldBeGreaterThanOrEqualsToTheLastDayOfTheYearWhenEndDateIsSmaller(): void
    {
        $startDate = new \DateTime('2024-01-10T21:30:02+00:00');
        $endDate = new \DateTime('2024-10-31T00:00:00+00:00');

        self::assertTrue(
            $this->subject->endDateShouldBeGreaterThanOrEqualsToTheLastDayOfTheYear($startDate, $endDate),
        );
    }

    public function testEndDateShouldBeGreaterThanOrEqualsToTheLastDayOfTheYearWhenEndDateIsGreater(): void
    {
        $startDate = new \DateTime('2024-10-15T10:22:00+00:00');
        $endDate = new \DateTime('2025-09-15T23:59:59+00:00');

        self::assertFalse(
            $this->subject->endDateShouldBeGreaterThanOrEqualsToTheLastDayOfTheYear($startDate, $endDate),
        );
    }

    public function testPeriodShouldNotExceedOneYearWithGoodDates(): void
    {
        $startDate = new \DateTime('2024-01-01T00:00:00+00:00');
        $endDate = new \DateTime('2024-12-31T23:59:59+00:00');

        self::assertTrue(
            $this->subject->periodShouldNotExceedOneYear($startDate, $endDate),
        );
    }

    public function testPeriodShouldNotExceedOneYearWhenThePeriodExceedsOneYear(): void
    {
        $startDate = new \DateTime('2024-01-01T00:00:00+00:00');
        $endDate = new \DateTime('2025-01-01T00:00:00+00:00');

        self::assertFalse(
            $this->subject->periodShouldNotExceedOneYear($startDate, $endDate),
        );

        $startDate = new \DateTime('2024-02-02T10:05:00+00:00');
        $endDate = new \DateTime('2025-03-01T12:09:09+00:00');

        self::assertFalse(
            $this->subject->periodShouldNotExceedOneYear($startDate, $endDate),
        );
    }

    public function testShouldBeGreaterThanWhenParamsAreCorrect(): void
    {
        $startDate = new \DateTime('2020-01-01T00:00:00+00:00');
        $endDate = new \DateTime('2020-01-01T00:00:01+00:00');

        self::assertTrue(
            $this->subject->shouldBeGreaterThan($startDate, $endDate),
        );
    }

    public function testShouldBeGreaterThanWhenEndDateIsLowerThanStartDate(): void
    {
        $startDate = new \DateTime('2020-01-01T00:00:01+00:00');
        $endDate = new \DateTime('2020-01-01T00:00:00+00:00');

        self::assertFalse(
            $this->subject->shouldBeGreaterThan($startDate, $endDate),
        );
    }

    public function testShouldBeGreaterThanNowWhenParamsAreCorrect(): void
    {
        self::assertTrue(
            $this->subject->shouldBeGreaterThanNow(
                new \DateTime('2200-01-01T00:00:00+00:00'),
            ),
        );
    }

    public function testShouldBeGreaterThanNowWhenDateIsLowerThanNow(): void
    {
        self::assertFalse(
            $this->subject->shouldBeGreaterThanNow(
                new \DateTime('1980-01-01T00:00:00+00:00'),
            ),
        );
    }
}
