<?php
/**
 * @package Hafenstudios\Kurato
 */

namespace Hafenstudios\Kurato\Booking;

defined( 'ABSPATH' ) || exit;

/**
 * Kalenderwochen-Rechnung fuer die Buchungsliste (K5-KONZEPT Abschnitt 7).
 *
 * Die Liste blaettert Woche fuer Woche (Montag-Start, Site-Zeitzone). Diese Klasse
 * haelt die reine Datumsrechnung frei von wpdb/HTTP und damit pruefbar: aus "jetzt"
 * (in Site-Zeit), einem Wochen-Offset und der Site-Zeitzone entsteht das
 * halboffene Fenster [Montag 00:00, naechster Montag 00:00) samt ISO-Kalenderwoche
 * und -Jahr. Jahres- und Sommerzeitwechsel laufen ausschliesslich ueber
 * DateTimeImmutable::modify, nie ueber Offset-Arithmetik (Muster SlotCalculator).
 */
final class BookingWeek {

	/**
	 * Fenster einer Woche relativ zu "jetzt".
	 *
	 * @param \DateTimeImmutable $now    Aktueller Zeitpunkt in der Site-Zeitzone.
	 * @param int                $offset Wochen-Offset (0 = aktuelle Woche, -1 = vorige).
	 * @return array{start:\DateTimeImmutable,end:\DateTimeImmutable,iso_year:int,iso_week:int}
	 *         start/end sind Site-Zeit (Montag 00:00 bis naechster Montag 00:00).
	 */
	public static function range( \DateTimeImmutable $now, int $offset = 0 ): array {
		// Auf Mitternacht des aktuellen Tages, dann auf den Montag dieser Woche.
		$midnight = $now->setTime( 0, 0, 0 );
		$dow      = (int) $midnight->format( 'N' ); // 1 (Mo) .. 7 (So).
		$monday   = $midnight->modify( '-' . ( $dow - 1 ) . ' days' );

		if ( 0 !== $offset ) {
			$sign   = $offset > 0 ? '+' : '-';
			$monday = $monday->modify( $sign . abs( $offset ) . ' weeks' );
			// Erneut auf 00:00 rasten, falls ein DST-Wechsel die Uhrzeit verschoben hat.
			$monday = $monday->setTime( 0, 0, 0 );
		}

		$next = $monday->modify( '+1 week' )->setTime( 0, 0, 0 );

		return array(
			'start'    => $monday,
			'end'      => $next,
			'iso_year' => (int) $monday->format( 'o' ),
			'iso_week' => (int) $monday->format( 'W' ),
		);
	}

	/**
	 * Wandelt eine Site-Zeit in einen UTC-'Y-m-d H:i:s'-String (fuer die
	 * Repository-Abfrage, die in UTC arbeitet).
	 *
	 * @param \DateTimeImmutable $site Zeit in der Site-Zeitzone.
	 * @return string
	 */
	public static function to_utc_string( \DateTimeImmutable $site ): string {
		return $site->setTimezone( new \DateTimeZone( 'UTC' ) )->format( 'Y-m-d H:i:s' );
	}
}
