<?php

namespace Planaday\Entities\DayPart\DTO;

use ArrayAccess;
use Countable;
use DateTime;
use DateTimeZone;
use Planaday\Entities\CostsData;
use Planaday\Entities\Location\DTO\Location;
use Traversable;

class DayPart {
	protected ?string $name = null;
	protected ?string $description = null;
	protected ?string $status = null;
	protected array $locationIds = [];
	/** @var Traversable<int,Location>&ArrayAccess<int,Location>&Countable  */
	protected ArrayAccess&Traversable&Countable $locations;
	protected array $instructors = [];
	protected ?DayPartUsersData $usersData = null;
	protected ?CostsData $costsData = null;
	protected bool $isELearning = false;
	protected bool $hasCode95 = false;
	protected array $labels = [];
	protected bool $visible = false;
	protected DateTime $startTime;
	protected ?DateTime $endTime;
	protected DateTime $lastUpdate;

	/**
	 * @param int $id
	 * @param int $courseId
	 */
	public function __construct(
		protected int $id,
		protected int $courseId
	) {
		$this->startTime = (new DateTime())->setTimezone(new DateTimeZone("Europe/Amsterdam"));
		$this->lastUpdate = (new DateTime())->setTimezone(new DateTimeZone("Europe/Amsterdam"));
	}

	public function setName( ?string $name ): self {
		$this->name = $name;

		return $this;
	}

	public function setDescription( ?string $description ): self {
		$this->description = $description;

		return $this;
	}

	public function setStatus( ?string $status ): self {
		$this->status = $status;

		return $this;
	}

	public function setLocationIds( ?array $locationIds ): self {
		$this->locationIds = $locationIds ?? $this->locationIds;

		return $this;
	}

	/**
	 * @param Traversable<int,Location>&ArrayAccess<int,Location>&Countable $locations
	 *
	 * @return $this
	 */
	public function setLocations( ArrayAccess&Traversable&Countable $locations ): self {
		$this->locations = $locations;

		return $this;
	}

	public function setInstructors( ?array $instructors ): self {
		$this->instructors = $instructors ?? $this->instructors;

		return $this;
	}

	public function setUsersData( ?DayPartUsersData $usersData ): self {
		$this->usersData = $usersData;

		return $this;
	}

	public function setCostsData( ?CostsData $costsData ): self {
		$this->costsData = $costsData;

		return $this;
	}

	public function setIsELearning( ?bool $isELearning ): self {
		$this->isELearning = $isELearning ?? $this->isELearning;

		return $this;
	}

	public function setHasCode95( ?bool $hasCode95 ): self {
		$this->hasCode95 = $hasCode95 ?? $this->hasCode95;

		return $this;
	}

	public function setLabels( ?array $labels ): self {
		$this->labels = $labels ?? $this->labels;

		return $this;
	}

	public function setVisible( ?bool $visible ): self {
		$this->visible = $visible ?? $this->visible;

		return $this;
	}

	public function setStartTime( DateTime $startTime ): self {
		$this->startTime = $startTime;

		return $this;
	}

	public function setEndTime( ?DateTime $endTime ): self {
		$this->endTime = $endTime;

		return $this;
	}

	public function setLastUpdate( DateTime $lastUpdate ): self {
		$this->lastUpdate = $lastUpdate;

		return $this;
	}

	public function getId(): int {
		return $this->id;
	}

	public function getCourseId(): int {
		return $this->courseId;
	}

	public function getName(): string {
		return $this->name ?? '';
	}

	public function getDescription(): string {
		return $this->description ?? '';
	}

	public function getStatus(): string {
		return $this->status ?? '';
	}

	/**
	 * @return string[]
	 */
	public function getLocationIds(): array {
		return $this->locationIds;
	}

	/**
	 * @return ArrayAccess<int, Location>&Traversable<int, Location>&Countable
	 */
	public function getLocations(): ArrayAccess&Traversable&Countable {
		return $this->locations;
	}

	/**
	 * @return int[]
	 */
	public function getInstructors(): array {
		return $this->instructors;
	}

	public function getUsersData(): DayPartUsersData {
		if( $this->usersData === null) {
			$this->usersData = new DayPartUsersData();
		}

		return $this->usersData;
	}

	public function getCostsData(): CostsData {
		if( $this->costsData === null) {
			$this->costsData = new CostsData();
		}

		return $this->costsData;
	}

	public function isELearning(): bool {
		return $this->isELearning;
	}

	public function isHasCode95(): bool {
		return $this->hasCode95;
	}

	/**
	 * @return string[]
	 */
	public function getLabels(): array {
		return $this->labels;
	}

	public function isVisible(): bool {
		return $this->visible;
	}

	public function getStartTime(): DateTime {
		return $this->startTime;
	}

	public function getEndTime(): ?DateTime {
		return $this->endTime;
	}

	public function getLastUpdate(): DateTime {
		return $this->lastUpdate;
	}

	public function getAge():int {
		return time() - $this->lastUpdate->getTimestamp();
	}
}