<?php

namespace Planaday\Html\Tags\Form\Booking\ExtraFieldsInput;

use Planaday\Api\ApiException\InvalidResponseException;
use Planaday\Entities\Booking\BookingController;
use Planaday\Entities\Booking\DTO\ExtraField;
use Planaday\Entities\Booking\PostRequest\BookingStudentFieldEnum;
use Planaday\Html\Tags\Form\DataInputFieldTag;
use Planaday\Html\Tags\Form\GenericInput\CheckboxInput\CheckboxInput;
use Planaday\Html\Tags\Form\GenericInput\RadioInput\RadioInput;
use Planaday\Html\Tags\Form\GenericInput\TextInput\TextInput;
use Planaday\Html\Tags\Form\SelectableDataInputFieldTag;
use Planaday\Utility\DependencyInjection\Container;
use Planaday\Utility\DependencyInjection\InjectionImpossibleException;

class ExtraFieldsInput extends DataInputFieldTag {
	const TAG = 'extra-fields-input';
	const DEFAULT_TEMPLATE = 'extraFieldsInput';
	protected string $fieldName = BookingStudentFieldEnum::EXTRA_FIELDS;

	protected BookingController $bookingController;

	/**
	 * @param Container $registry
	 *
	 * @throws InjectionImpossibleException
	 */
	public function __construct(Container $registry) {
		$this->bookingController = $registry->getInstance(BookingController::class);
		parent::__construct(__DIR__, self::DEFAULT_TEMPLATE, $registry);
	}

	public function buildTag(): string {
		$parser = $this->getNewParser();

		try {
			$extraFields = $this->bookingController->getExtraFields();
		} catch ( InvalidResponseException ) {
			return $parser->parse($this->getErrorTemplate());
		}

		if (count($extraFields) == 0)
			return $parser->parse($this->getErrorTemplate('', 'noExtraFields'));

		$extraFieldsHtml = '';
		foreach ($extraFields as $extraField){
			$extraFieldsHtml .= $this->buildExtraFieldHtml($extraField);
		}

		$parser->setUnsafeData('fields', $extraFieldsHtml);
		return $parser->parse($this->getTemplate());
	}

	/**
	 * @param ExtraField<string|int> $extraField
	 *
	 * @return string
	 */
	protected function buildExtraFieldHtml(ExtraField $extraField): string{
		$parser = $this->getNewParser();

		$parser->injectAttribute(
			SelectableDataInputFieldTag::FIELD_CLASS_ATTRIBUTE,
			BookingStudentFieldEnum::class
		);

		$errors = $this->getFieldErrors();
		if (is_array($errors) && key_exists($extraField->getId(), $errors))
			$parser->setData('error-label', 'pad-form-error-label');
		$parser->setData('name', $extraField->getName());
		$parser->setCondition('required', $extraField->isRequired());
		$description = $extraField->getDescription();
		$parser->setCondition('hasDescription', !empty($description));
		$parser->setData('description', $description);

		$inputHtml = '';
		switch ($extraField->getType()){
			case 'textfield':
				$inputHtml .= TextInput::getTagHtml(
					'' . $extraField->getId(),
					'',
					$extraField->getName(),
					is_array($extraField->getDefaultValue()) ? implode(', ', $extraField->getDefaultValue()) : '' . $extraField->getDefaultValue()
				);
				break;
			case 'checkbox':
				foreach ($extraField->getOptions() as $value){
					$inputHtml .= CheckboxInput::getTagHtml(
						'' . $extraField->getId(),
						'' . $value,
						'' . $value,
						'' . $value,
						(is_array($extraField->getDefaultValue()) && in_array($value, $extraField->getDefaultValue())),
						true
					);
				}
				break;
			case 'selectbox':
			case 'radiobutton':
				foreach ($extraField->getOptions() as $value){
					$inputHtml .= RadioInput::getTagHtml(
						'' . $extraField->getId(),
						'' . $value,
						'' . $value,
						'' . $value,
						($value == $extraField->getDefaultValue())
					);
				}
				break;
		}
		$parser->setUnsafeData('inputs', $inputHtml);

		return $parser->parse($this->getTemplate('ExtraField'));
	}
}