<?php
/**
 * Class representing a day of the week time availability.
 *
 * @package flo-sync
 */

namespace NMFS\Sync\Items\Article_Availabilities\Models\Schedules;

use NMFS\Sync\Items\Article_Availabilities\Models\Schedules\Periods\Day_Time_Period_Model;
use Northmill_Online_Shared_Sync\Northmill_Online_Shared\Traits\Json_Decode_Trait;

/**
 * Class Day_Of_Week_Time_Availability_Model
 */
class Day_Of_Week_Schedule_Model implements Schedule_Interface {
	use Json_Decode_Trait;

	/**
	 * Day of the week.
	 * 0 = Sunday, 1 = Monday, ..., 6 = Saturday.
	 *
	 * @var int
	 */
	public int $day_of_week;

	/**
	 * Time periods for the day of the week.
	 *
	 * @var Day_Time_Period_Model[]
	 */
	public array $time_periods;

	/**
	 * Check if the current time is within the availability time range.
	 *
	 * @return bool.
	 */
	public function is_available_now(): bool {
		$day_of_week = (int) current_time( 'w' );
		if ( $day_of_week !== $this->day_of_week ) {
			return false;
		}

		foreach ( $this->time_periods as $time_period ) {
			if ( $time_period->is_now_within_time_range() ) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Specify data which should be serialized to JSON
	 */
	public function jsonSerialize(): array {
		return array(
			'day_of_week'  => $this->day_of_week,
			'time_periods' => $this->time_periods,
		);
	}

	/**
	 * Takes a JSON string matching what is returned by jsonSerialize() and returns an instance of the class.
	 *
	 * @param string|array $data JSON data. This is either a JSON string or an already decoded array.
	 *
	 * @return static|null The instance of the class, or null if the data is invalid.
	 */
	public static function jsonUnserialize( string|array $data ): ?static {
		$data = self::decode_json_data( $data );
		if ( ! $data ) {
			return null;
		}

		$instance               = new self();
		$instance->day_of_week  = (int) $data['day_of_week'];
		$instance->time_periods = array_map(
			fn( $time_period_data ) => Day_Time_Period_Model::jsonUnserialize( $time_period_data ),
			$data['time_periods']
		);

		return $instance;
	}
}
