<?php

declare(strict_types=1);

namespace Tests\Framework\DateTime;

use App\Framework\DateTime\DateRange;

class DateRangeTest extends \PHPUnit\Framework\TestCase
{
    public function testConstructorWithValidDates(): void
    {
        $start = new \DateTimeImmutable('2021-01-01');
        $end = new \DateTimeImmutable('2021-01-31');

        $range = new DateRange($start, $end);

        $this->assertSame($start, $range->getStart());
        $this->assertSame($end, $range->getEnd());
    }

    public function testConstructorWithInvalidDatesThrowsException(): void
    {
        $start = new \DateTimeImmutable('2021-01-31');
        $end = new \DateTimeImmutable('2021-01-01');

        $this->expectException(\InvalidArgumentException::class);
        new DateRange($start, $end);
    }

    public function testFromStrings(): void
    {
        $range = DateRange::fromStrings('2021-01-01', '2021-01-31');

        $this->assertEquals('2021-01-01', $range->getStart()->format('Y-m-d'));
        $this->assertEquals('2021-01-31', $range->getEnd()->format('Y-m-d'));
    }

    public function testContains(): void
    {
        $range = DateRange::fromStrings('2021-01-01', '2021-01-31');

        $inside = new \DateTimeImmutable('2021-01-15');
        $onStart = new \DateTimeImmutable('2021-01-01');
        $onEnd = new \DateTimeImmutable('2021-01-31');
        $before = new \DateTimeImmutable('2020-12-31');
        $after = new \DateTimeImmutable('2021-02-01');

        $this->assertTrue($range->contains($inside));
        $this->assertTrue($range->contains($onStart));
        $this->assertTrue($range->contains($onEnd));
        $this->assertFalse($range->contains($before));
        $this->assertFalse($range->contains($after));
    }

    public function testContainsRange(): void
    {
        $mainRange = DateRange::fromStrings('2021-01-01', '2021-01-31');

        $inside = DateRange::fromStrings('2021-01-10', '2021-01-20');
        $sameRange = DateRange::fromStrings('2021-01-01', '2021-01-31');
        $overlapping = DateRange::fromStrings('2021-01-15', '2021-02-15');
        $outside = DateRange::fromStrings('2021-02-01', '2021-02-28');

        $this->assertTrue($mainRange->containsRange($inside));
        $this->assertTrue($mainRange->containsRange($sameRange));
        $this->assertFalse($mainRange->containsRange($overlapping));
        $this->assertFalse($mainRange->containsRange($outside));
    }

    public function testOverlaps(): void
    {
        $mainRange = DateRange::fromStrings('2021-01-01', '2021-01-31');

        $inside = DateRange::fromStrings('2021-01-10', '2021-01-20');
        $overlappingStart = DateRange::fromStrings('2020-12-15', '2021-01-15');
        $overlappingEnd = DateRange::fromStrings('2021-01-15', '2021-02-15');
        $outside = DateRange::fromStrings('2021-02-01', '2021-02-28');

        $this->assertTrue($mainRange->overlaps($inside));
        $this->assertTrue($mainRange->overlaps($overlappingStart));
        $this->assertTrue($mainRange->overlaps($overlappingEnd));
        $this->assertFalse($mainRange->overlaps($outside));
    }

    public function testGetDuration(): void
    {
        $range = DateRange::fromStrings('2021-01-01', '2021-01-31');
        $duration = $range->getDuration();

        $this->assertInstanceOf(\DateInterval::class, $duration);
        $this->assertEquals(30, $duration->days);
    }

    public function testGetDurationInSeconds(): void
    {
        $range = DateRange::fromStrings('2021-01-01', '2021-01-02');
        $seconds = $range->getDurationInSeconds();

        // Ein Tag hat 86400 Sekunden
        $this->assertEquals(86400, $seconds);
    }
}
