<?php

declare(strict_types=1);

namespace Tests\Framework\DateTime;

use App\Framework\DateTime\DateTime;
use App\Framework\DateTime\Exceptions\InvalidDateTimeException;
use App\Framework\DateTime\Exceptions\InvalidTimezoneException;
use PHPUnit\Framework\TestCase;

class DateTimeTest extends TestCase
{
    protected function setUp(): void
    {
        // Sicherheitsvorkehrung: Default-Timezone vor jedem Test zurücksetzen
        if (method_exists(DateTime::class, 'setDefaultTimezone')) {
            DateTime::setDefaultTimezone('UTC');
        }
    }

    // Removed: now() functionality is provided by Clock implementations
    // See SystemClockTest and FrozenClockTest for equivalent functionality

    public function testFromTimestamp(): void
    {
        $timestamp = 1609459200; // 2021-01-01 00:00:00 UTC
        $date = DateTime::fromTimestamp($timestamp);

        $this->assertEquals($timestamp, $date->getTimestamp());
        $this->assertEquals('UTC', $date->getTimezone()->getName());
    }

    public function testFromString(): void
    {
        $date = DateTime::fromString('2021-01-01 12:00:00');

        $this->assertEquals('2021-01-01 12:00:00', $date->format('Y-m-d H:i:s'));
        $this->assertEquals('UTC', $date->getTimezone()->getName());
    }

    public function testFromFormat(): void
    {
        $date = DateTime::fromFormat('01/01/2021', 'd/m/Y');

        $this->assertEquals('2021-01-01', $date->format('Y-m-d'));
    }

    public function testFromDateTime(): void
    {
        $originalDate = new \DateTime('2021-01-01 12:00:00');
        $immutableDate = DateTime::fromDateTime($originalDate);

        $this->assertInstanceOf(\DateTimeImmutable::class, $immutableDate);
        $this->assertEquals($originalDate->format('Y-m-d H:i:s'), $immutableDate->format('Y-m-d H:i:s'));
    }

    public function testCreateInterval(): void
    {
        $interval = DateTime::createInterval('P1D');

        $this->assertInstanceOf(\DateInterval::class, $interval);
        $this->assertEquals(1, $interval->d);
    }

    public function testCreateTimezone(): void
    {
        $timezone = DateTime::createTimezone('Europe/Berlin');

        $this->assertInstanceOf(\DateTimeZone::class, $timezone);
        $this->assertEquals('Europe/Berlin', $timezone->getName());
    }

    public function testInvalidTimezoneThrowsException(): void
    {
        $this->expectException(InvalidTimezoneException::class);
        DateTime::createTimezone('Invalid/Timezone');
    }

    public function testInvalidDateTimeThrowsException(): void
    {
        $this->expectException(InvalidDateTimeException::class);
        DateTime::fromString('not a date');
    }

    public function testInvalidFormatThrowsException(): void
    {
        $this->expectException(InvalidDateTimeException::class);
        DateTime::fromFormat('2021-01-01', 'invalid format');
    }

    public function testInvalidIntervalThrowsException(): void
    {
        $this->expectException(InvalidDateTimeException::class);
        DateTime::createInterval('invalid interval');
    }

    // Removed: setDefaultTimezone, today, tomorrow, yesterday functionality
    // is provided by Clock implementations
    // See SystemClockTest and FrozenClockTest for equivalent functionality

    public function testSetDefaultTimezone(): void
    {
        // Test the setDefaultTimezone method that actually exists
        DateTime::setDefaultTimezone('Europe/Berlin');

        $timezone = DateTime::getDefaultTimezone();
        $this->assertEquals('Europe/Berlin', $timezone->getName());

        // Reset to UTC for other tests
        DateTime::setDefaultTimezone('UTC');
    }
}
