<?php

namespace SugarCalendarBookings\Availability;

use DateTimeImmutable;
use DateTimeZone;
use Exception;
use SugarCalendarBookings\Employees\EmployeeModel;

/**
 * Working schedule override rule.
 *
 * @since 1.0.0
 */
class WorkingScheduleDateRangeRule extends AbstractWorkingScheduleRule {

	/**
	 * Start date.
	 *
	 * @since 1.0.0
	 *
	 * @var DateTimeImmutable Start date.
	 */
	private $start_date;

	/**
	 * End date.
	 *
	 * @since 1.0.0
	 *
	 * @var DateTimeImmutable End date.
	 */
	private $end_date;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param DateTimeImmutable        $start_date Start date.
	 * @param DateTimeImmutable        $end_date   End date.
	 * @param array<WorkingPeriodRule> $periods    Periods.
	 * @param DateTimeZone             $time_zone  Time zone.
	 * @param EmployeeModel            $employee   Employee model.
	 * @param int                      $priority   Priority.
	 */
	public function __construct( $start_date, $end_date, $periods, $time_zone, $employee, $priority ) {

		parent::__construct( $periods, $time_zone, $employee, $priority );

		$this->start_date = $start_date;
		$this->end_date   = $end_date;
	}

	/**
	 * Get start date.
	 *
	 * @since 1.0.0
	 *
	 * @return DateTimeImmutable Start date.
	 */
	public function get_start_date() {

		return $this->start_date;
	}

	/**
	 * Get end date.
	 *
	 * @since 1.0.0
	 *
	 * @return DateTimeImmutable End date.
	 */
	public function get_end_date() {

		return $this->end_date;
	}

	/**
	 * Create a working schedule override rule from an array.
	 *
	 * @since 1.0.0
	 *
	 * @param array         $data      Data.
	 * @param DateTimeZone  $time_zone Time zone.
	 * @param EmployeeModel $employee  Employee model.
	 * @param int           $priority  Priority.
	 *
	 * @return WorkingScheduleDateRangeRule|null Working schedule override rule.
	 */
	public static function from_array( $data, $time_zone, $employee, $priority ) {

		if (
			! isset( $data['start_date'], $data['end_date'], $data['periods'] ) ||
			! is_array( $data['periods'] )
		) {
			return null;
		}

		try {
			$start_date = ( new DateTimeImmutable( $data['start_date'], $time_zone ) )->setTime( 0, 0, 0 );
			$end_date   = ( new DateTimeImmutable( $data['end_date'], $time_zone ) )->setTime( 23, 59, 59 );
		} catch ( Exception $e ) {
			return null;
		}

		$periods = array_map( fn( $period ) => WorkingPeriodRule::from_array( $period, $time_zone, $employee ), $data['periods'] );

		return new self( $start_date, $end_date, array_filter( $periods ), $time_zone, $employee, $priority );
	}
}
