<?php

namespace Planaday\Database\SQLDatabaseControllers\DayPart;

use ArrayAccess;
use Countable;
use Planaday\Database\SQLDatabaseControllers\Database;
use Planaday\Entities\DayPart\DayPartDatabase;
use Planaday\Entities\DayPart\DTO\DayPart;
use Traversable;

class SQLDayPartDatabase implements DayPartDatabase, Database {
	public function __construct(
		protected DayPartTable $dayPartTable,
		protected DayPartInstructorLink $dayPartInstructorLink,
		protected DayPartLocationLink $dayPartLocationLink
	) {}

	public function setDayPart( DayPart $dayPart ): void {
		$this->dayPartTable->setDayPart($dayPart);
	}

	/**
	 * @param int $courseId
	 *
	 * @return ArrayAccess<int|string, DayPart>&Traversable<int|string, DayPart>&Countable
	 */
	public function getDayPartsByCourseId( int $courseId ): ArrayAccess&Traversable&Countable {
		return $this->dayPartTable->getDayPartsByCourseId($courseId);
	}

	public function getDayPartById( int $id ): ?DayPart {
		return $this->dayPartTable->getDayPartById($id);
	}

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

	/**
	 *
	 * @param ArrayAccess<int|string, DayPart>&Traversable<int|string, DayPart>&Countable $dayParts
	 * @param bool $wipeDB *
	 *
	 * @return void
	 */
	public function setAll( ArrayAccess&Traversable&Countable $dayParts, bool $wipeDB = false ): void {
		$this->dayPartTable->setAll($dayParts, $wipeDB);
	}

	public function getCreateTableQuery( bool $force = false ): string {
		$outputQuery = '';

		if (!$this->dayPartTable->isTableValid() || $force )
			$outputQuery .= $this->dayPartTable->getDropTableQuery() . $this->dayPartTable->getCreateTableQuery();
		if (!$this->dayPartLocationLink->isTableValid() || $force )
			$outputQuery .= $this->dayPartLocationLink->getDropTableQuery() . $this->dayPartLocationLink->getCreateTableQuery();
		if (!$this->dayPartInstructorLink->isTableValid() || $force )
			$outputQuery .= $this->dayPartInstructorLink->getDropTableQuery() . $this->dayPartInstructorLink->getCreateTableQuery();

		return $outputQuery;
	}

	public function getDropTableQuery(): string {
		$outputQuery = $this->dayPartTable->getDropTableQuery();
		$outputQuery .= $this->dayPartLocationLink->getDropTableQuery();
		$outputQuery .= $this->dayPartInstructorLink->getDropTableQuery();

		return $outputQuery;
	}

	public function isDatabaseValid(): bool {
		return $this->dayPartTable->isTableValid() &&
		       $this->dayPartLocationLink->isTableValid() &&
		       $this->dayPartInstructorLink->isTableValid();
	}

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

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

	public function rebuildTables(): void {
		$this->dayPartInstructorLink->rebuildTable();
		$this->dayPartLocationLink->rebuildTable();
		$this->dayPartTable->rebuildTable();
	}
}