<?php

namespace Planaday\Html\NodeTags\Booking\Form;

use Planaday\Api\ApiException\InvalidResponseException;
use Planaday\Config\Booking\Submission\Redirecting\RedirectSettings;
use Planaday\Config\Course\General\GeneralSettings;
use Planaday\Entities\Booking\DTO\BookingForm;
use Planaday\Entities\Booking\Form\BookingFormFactory;
use Planaday\Entities\Booking\Form\BookingFormSettings;
use Planaday\Entities\Course\DTO\Course;
use Planaday\Entities\Course\Exception\CourseNotFoundException;
use Planaday\Html\Nodes\NodeData;
use Planaday\Html\NodeTags\Tag;
use Planaday\Html\NodeTags\TemplateOnlyTag;
use Planaday\Html\Parsers\NodeParsers\TagMarkers\RefreshUniqueId;
use Planaday\Platform\PlatformAbstraction\DataHandler;
use Planaday\Platform\PlatformAbstraction\LocalizationController;
use Planaday\Platform\PlatformAbstraction\UrlHandler;
use Planaday\Utility\DataGrouping\UUIDGenerator;
use Planaday\Utility\DependencyInjection\Attributes\Transient;
use Planaday\Utility\FormBuilder\LayoutItems\MessageDisplay;
use Planaday\Utility\FormBuilder\LayoutItems\SubmitButton;
use Planaday\Utility\FormBuilder\SubmitStrategies\RestSubmit;
use Planaday\Utility\FormBuilder;

#[Transient]
class Form implements RefreshUniqueId, Tag {
	use TemplateOnlyTag;

	public function __construct(
		protected LocalizationController $translator,
		protected BookingFormFactory $bookingFormFactory,
		protected UrlHandler $urlHandler,
		protected DataHandler $dataHandler,
		protected RedirectSettings $redirectSettings,
		protected FormTagSettings $formTagSettings,
		protected BookingFormSettings $bookingFormSettings,
		protected GeneralSettings $generalSettings
	) {}

	public function prepareData( NodeData $nodeData ): void {
		$t = function (string $text) {return $this->translator->translate($text);};

		$course = $this->attributes["course"] ?? $this->nodeData->data["course"] ?? null;
		$allowBookingOnPastDates = $this->bookingFormSettings->isStartedCourseBookable();
		$courseStartedMessage = $this->formTagSettings->getCourseStartedMessage();
		$courseFullMessage = $this->formTagSettings->getCourseFullMessage();

		//load settings for redirect
		$this->redirectSettings->getFailureText();
		$this->redirectSettings->getFailurePage();
		$this->redirectSettings->getSuccessPage();
		$this->redirectSettings->getSuccessText();
		$this->redirectSettings->isRedirectAfterFailure();
		$this->redirectSettings->isRedirectAfterSuccess();

		if (!$course instanceof Course){
			return;
		}

		if (!$allowBookingOnPastDates && $course->hasPastDayParts($this->generalSettings->isELearningCountsAsStart())){
			$nodeData->data["message"] = $courseStartedMessage;
			$nodeData->data["showForm"] = false;
			return;
		}

		if ($course->getUsersData()->getAvailableSpots($this->generalSettings->isIncludeOptionInCount()) <= 0){
			$nodeData->data["message"] = $courseFullMessage;
			$nodeData->data["showForm"] = false;
			return;
		}

		$nodeData->data["showForm"] = true;
		$nodeData->data["pageId"] = $this->urlHandler->getCurrentPageId();
		$nodeData->data["BookingFormNonce"] = UUIDGenerator::generateUUIDv4OrRandom();

		$bookingForm = new BookingForm();
		$bookingForm->setCourseId($course->getId());

		try{
			$form = (new FormBuilder\Form())
				->setName('bookingForm')
				->setSubmitBehaviour(
					( new RestSubmit() )
						->setUrl($this->urlHandler->getRestApiPrefix() . 'booking/course/' . $course->getId())
						->setHeaders($this->dataHandler->getRestNonceHeader())
				)
				->addContents(
					$this->bookingFormFactory->getFormForObject($bookingForm),
					new MessageDisplay(),
					new SubmitButton($t('Boek Cursus'))
				);

			$nodeData->data["formJson"] = json_encode( $form );
		} catch (InvalidResponseException|CourseNotFoundException $e){
			$this->logWarning( $e->getMessage() );
		}
	}

	public function getTagDir(): string {
		return __DIR__;
	}
}