<?php

namespace Planaday\Database\SQLDatabaseControllers\DayPart;

use DateTime;
use DateTimeZone;
use Planaday\Entities\CostsData;
use Planaday\Entities\DayPart\DTO\DayPart;
use Planaday\Entities\DayPart\DTO\DayPartUsersData;

class DayPartDatabaseObject {
	/**
	 * @param DayPart $dayPart
	 *
	 * @return array<mixed>
	 */
	public static function getDatabaseArrayFromDayPart(DayPart $dayPart): array{
		$data = [];
		$data[DayPartColumnEnum::USERS_SCHEDULED] = $dayPart->getUsersData()->getScheduled();
		$data[DayPartColumnEnum::USERS_AVAILABLE] = $dayPart->getUsersData()->getAvailable();
		$data[DayPartColumnEnum::USERS_OPTIONS] = $dayPart->getUsersData()->getOptions();
		$data[DayPartColumnEnum::USERS_WAITING_LIST] = $dayPart->getUsersData()->getWaitingList();
		$data[DayPartColumnEnum::USERS_MIN] = $dayPart->getUsersData()->getMin();
		$data[DayPartColumnEnum::USERS_MAX] = $dayPart->getUsersData()->getMax();
		$data[DayPartColumnEnum::COST] = $dayPart->getCostsData()->getCost();
		$data[DayPartColumnEnum::VAT] = $dayPart->getCostsData()->getVat();
		$data[DayPartColumnEnum::VAT_CODE] = $dayPart->getCostsData()->getVatCode();
		$data[DayPartColumnEnum::ID] = $dayPart->getId();
		$data[DayPartColumnEnum::COURSE_ID] = $dayPart->getCourseId();
		$data[DayPartColumnEnum::NAME] = $dayPart->getName();
		$data[DayPartColumnEnum::DESCRIPTION] = $dayPart->getDescription();
		$data[DayPartColumnEnum::STATUS] = $dayPart->getStatus();
		$data[DayPartColumnEnum::IS_E_LEARNING] = $dayPart->isELearning();
		$data[DayPartColumnEnum::HAS_CODE_95] = $dayPart->isHasCode95();
		$data[DayPartColumnEnum::LABELS] = '|' . implode('|', $dayPart->getLabels()) . '|';
		$data[DayPartColumnEnum::IS_VISIBLE] = $dayPart->isVisible();
		$data[DayPartColumnEnum::START_TIME] = $dayPart->getStartTime()->format('Y-m-d H:i:s');
		$data[DayPartColumnEnum::END_TIME] = $dayPart->getEndTime()?->format('Y-m-d H:i:s');
		$data[DayPartColumnEnum::LAST_UPDATE] = $dayPart->getLastUpdate()->format('Y-m-d H:i:s');

		return $data;
	}

	/**
	 * @param array<mixed> $data
	 * @param string[] $locations
	 * @param int[] $instructors
	 *
	 * @return DayPart
	 */
	public static function getDayPartObject(array $data, array $locations, array $instructors): DayPart{
		$lastUpdatedTime = DateTime::createFromFormat(
			"Y-m-d H:i:s",
			$data[DayPartColumnEnum::LAST_UPDATE],
			new DateTimeZone('Europe/Amsterdam')
		);

		if ( $lastUpdatedTime === false )
			$lastUpdatedTime = (new DateTime())->setTimestamp(0);

		$startTime = DateTime::createFromFormat(
			'Y-m-d H:i:s',
			$data[DayPartColumnEnum::START_TIME],
			new DateTimeZone('Europe/Amsterdam')
		);

		if ( $startTime === false )
			$startTime = (new DateTime())->setTimestamp(0);

		$endTime = DateTime::createFromFormat(
			'Y-m-d H:i:s',
			$data[DayPartColumnEnum::END_TIME],
			new DateTimeZone('Europe/Amsterdam')
		);

		if ( $endTime === false )
			$endTime = null;

		return (new DayPart( $data[DayPartColumnEnum::ID], $data[DayPartColumnEnum::COURSE_ID]))
			->setName($data[DayPartColumnEnum::NAME])
			->setDescription($data[DayPartColumnEnum::DESCRIPTION])
			->setStatus($data[DayPartColumnEnum::STATUS])
			->setLocationIds($locations)
			->setInstructors($instructors)
			->setUsersData(
				(new DayPartUsersData())
					->setScheduled($data[DayPartColumnEnum::USERS_SCHEDULED])
					->setAvailable($data[DayPartColumnEnum::USERS_AVAILABLE])
					->setOptions($data[DayPartColumnEnum::USERS_OPTIONS])
					->setWaitingList($data[DayPartColumnEnum::USERS_WAITING_LIST])
					->setMin($data[DayPartColumnEnum::USERS_MIN])
					->setMax($data[DayPartColumnEnum::USERS_MAX])
			)->setCostsData(
				(new CostsData())
					->setCost($data[DayPartColumnEnum::COST])
					->setVat($data[DayPartColumnEnum::VAT])
					->setVatCode($data[DayPartColumnEnum::VAT_CODE])
			)->setIsElearning($data[DayPartColumnEnum::IS_E_LEARNING])
			->setHasCode95($data[DayPartColumnEnum::HAS_CODE_95])
			->setLabels(
				empty($data[DayPartColumnEnum::LABELS]) || empty(substr($data[DayPartColumnEnum::LABELS], 1, -1)) ?
					[] :
					explode('|', substr($data[DayPartColumnEnum::LABELS], 1, -1))
			)
			->setVisible($data[DayPartColumnEnum::IS_VISIBLE])
			->setStartTime($startTime)
			->setEndTime($endTime)
			->setLastUpdate($lastUpdatedTime);
	}
}