<?php
/**
 * UTC timestamp value object.
 *
 * @package ScheduledChanges
 */

namespace ScheduledChanges\Domain\Shared;

/**
 * Immutable UTC timestamp with storage conversion.
 */
final class UtcTimestamp {
	private \DateTimeImmutable $value;
	/**
	 * Creates a UTC timestamp.
	 *
	 * @param \DateTimeImmutable $value Date and time.
	 */
	public function __construct( \DateTimeImmutable $value ) {
		$this->value = $value;
		if ( 'UTC' !== $value->getTimezone()->getName() ) {
			throw new \InvalidArgumentException( 'UtcTimestamp requires the UTC timezone.' );
		}
	}

	/**
	 * Current UTC time.
	 */
	public static function now(): self {
		return new self( new \DateTimeImmutable( 'now', new \DateTimeZone( 'UTC' ) ) );
	}

	/**
	 * Creates a timestamp from database storage.
	 *
	 * @param string $value MySQL UTC datetime.
	 */
	public static function fromStorage( string $value ): self {
		$date = \DateTimeImmutable::createFromFormat(
			'!Y-m-d H:i:s',
			$value,
			new \DateTimeZone( 'UTC' )
		);

		if ( false === $date ) {
			throw new \InvalidArgumentException( 'Invalid UTC storage timestamp.' );
		}

		return new self( $date );
	}

	/**
	 * Native value.
	 */
	public function native(): \DateTimeImmutable {
		return $this->value;
	}

	/**
	 * MySQL storage value.
	 */
	public function toStorage(): string {
		return $this->value->format( 'Y-m-d H:i:s' );
	}

	/**
	 * ISO 8601 value.
	 */
	public function toIso8601(): string {
		return $this->value->format( \DateTimeInterface::ATOM );
	}
}
