<?php

namespace Planaday\Database\InMemoryDatabase;

use ArrayAccess;
use Countable;
use Planaday\Entities\Course\CourseDatabase;
use Planaday\Entities\Course\DTO\Course;
use Planaday\Entities\Course\DTO\CourseSearch;
use Planaday\Utility\DataGrouping\Collection;
use Planaday\Utility\DataGrouping\Map;
use Traversable;

class InMemoryCourseDB implements CourseDatabase{
	/** @var Course[] */
	public array $courses = [];
	public ?array $searchResults = null;
	public ?CourseSearch $lastSearch = null;

	public function setCourse( Course $course ): void {
		$this->courses[$course->getId()] = $course;
	}

	public function getCourseById( int $id ): ?Course {
		return $this->courses[$id] ?? null;
	}

	public function getCoursesBySearch( CourseSearch $search ): ArrayAccess&Traversable&Countable {
		$this->lastSearch = $search;
		return Collection::fromArray($this->searchResults ?? $this->courses);
	}

	public function getCoursesByTimeSlot( int $startDate, int $endDate ): ArrayAccess&Traversable&Countable {
		$courses = [];
		foreach ($this->courses as $course){
			foreach ($course->getDayParts() as $dayPart) {
				if($dayPart->getDate() >= $startDate && $dayPart->getDate() <= $endDate){
					$courses[] = $course;
					break;
				}
			}
		}
		return Collection::fromArray($courses);
	}

	public function getUniqueLabelsCourse(): ArrayAccess&Traversable&Countable {
		$labels = [];
		foreach ($this->courses as $course){
			$labels[] = array_merge($labels, $course->getLabels());
		}
		return Collection::fromArray(array_unique($labels));
	}

	public function setAll( Countable&Traversable&ArrayAccess $courses, bool $wipeDB = false ): void {
		if ($wipeDB) $this->courses = [];
		foreach ($courses as $course){
			$this->courses[$course->getId()] = $course;
		}
	}

	public function getAll(): ArrayAccess&Traversable&Countable {
		return Collection::fromArray($this->courses);
	}

	public function getAllRaw(): ArrayAccess&Traversable&Countable {
		return Map::fromArray($this->courses);
	}

	public function getCountAll(): int {
		return count($this->courses);
	}
}