<?php

namespace Planaday\Database\SQLDatabaseControllers\Booking;

use ArrayAccess;
use Countable;
use Planaday\Database\Abstraction\SQLQuery\ColumnTypeMap;
use Planaday\Database\Abstraction\SQLQuery\QueryBuilding\SQLColumn;
use Planaday\Database\Abstraction\SQLQuery\SQLFactory;
use Planaday\Database\SQLDatabaseControllers\DayPart\DayPartColumnEnum;
use Planaday\Database\SQLDatabaseControllers\DayPart\DayPartTable;
use Planaday\Database\SQLDatabaseControllers\LinkingTable;
use Planaday\Platform\PlatformAbstraction\DatabaseInterface;
use Traversable;

class BookingDayPartLink extends LinkingTable {
	public const DAY_PART_BOOKING_LINK_TABLE = 'day_part_booking_link';

	protected SQLColumn $columnDayPart;
	protected SQLColumn $columnBooking;

	/** @noinspection PhpMissingParentConstructorInspection constructor is overridden of parents*/
	public function __construct( DatabaseInterface $querySender, SQLFactory $sql, ColumnTypeMap $columnTypeMap ) {
		$this->columnDayPart = $sql->table(
			$querySender->convertTableString(DayPartTable::DAY_PART_TABLE)
		)->getColumn(
			DayPartColumnEnum::ID
		);

		$this->columnBooking = $sql->table(
			$querySender->convertTableString(BookingTable::BOOKING_TABLE)
		)->getColumn(
			BookingTable::ID_COLUMN
		);


		$columns = [];
		$column1Name = str_replace('.', '_', $this->columnBooking->getFullColumnIdentifier());
		$column2Name = str_replace('.', '_', $this->columnDayPart->getFullColumnIdentifier());

		$columns[$column1Name] = implode(" ", [
			$columnTypeMap->UUID(),
			$columnTypeMap->NOT_NULL()
		]);
		$columns[$column2Name] = implode(" ", [
			$columnTypeMap->ID(),
			$columnTypeMap->NOT_NULL()
		]);

		$constraints = [
			'CombinedPK' => "PRIMARY KEY ($column1Name, $column2Name)"
		];

		$this->querySender = $querySender;
		$this->sql         = $sql;
		$this->name    = self::DAY_PART_BOOKING_LINK_TABLE;
		$this->columns = $columns;
		$this->constraints = $constraints;
		$this->initializeTable();
	}

	/**
	 * @param string $bookingId
	 *
	 * @return ArrayAccess<string>&Traversable<string>&Countable
	 */
	public function getDayPartsForBooking(string $bookingId): ArrayAccess&Traversable&Countable {
		return $this->getConnections($bookingId, $this->columnBooking, $this->columnDayPart);
	}

	/**
	 * @param string $bookingId
	 * @param ArrayAccess<int>&Traversable<int>&Countable $dayPartIds
	 *
	 * @return void
	 */
	public function setDayPartsForBooking(string $bookingId, ArrayAccess&Traversable&Countable $dayPartIds): void {
		$this->setConnections($bookingId, $dayPartIds, $this->columnBooking, $this->columnDayPart);
	}
}