<?php

namespace Planaday\Html\NodeTags\Course\Search;

use Planaday\Config\BasicEnumMappedSetting;
use Planaday\Config\EnumMappedSettings;
use Planaday\Config\FormGroupable;
use Planaday\Config\SettingsLoader;
use Planaday\Config\SettingsWithForm;
use Planaday\Platform\PlatformAbstraction\LocalizationController;
use Planaday\Platform\PlatformAbstraction\UrlHandler;
use Planaday\Utility\DependencyInjection\Attributes\Scoped;
use Planaday\Utility\FormBuilder\Conditions\InputValueCondition;
use Planaday\Utility\FormBuilder\DataTypes\IntType;
use Planaday\Utility\FormBuilder\InputFields\BoolInput;
use Planaday\Utility\FormBuilder\InputFields\SelectionInput;
use Planaday\Utility\FormBuilder\InputFields\StringInput;
use Planaday\Utility\FormBuilder\LayoutItems\Text;
use Planaday\Utility\FormBuilder\Structures\BasicGroup;
use Planaday\Utility\FormBuilder\Structures\CollapsibleGroup;
use Planaday\Utility\FormBuilder\Validators\Required;

#[Scoped]
class SearchSettings implements EnumMappedSettings, SettingsWithForm {
	use FormGroupable;
	use BasicEnumMappedSetting;

	protected bool $askTitle = true;
	protected bool $askLocation = false;
	protected bool $askLabels = false;
	protected bool $askELearning = false;
	protected bool $askSoob = false;
	protected bool $askStap = false;
	protected bool $askCode95 = false;
	protected int $pageToSendTo = 0;
	protected string $formTitle = "Zoek";

	public function __construct(
		protected LocalizationController $localizationController,
		protected UrlHandler $urlHandler,
		SettingsLoader $settingsLoader
	) {
		$settingsLoader->reloadData($this, SearchOptionsEnum::class);
	}

	protected function createFormGroup(): CollapsibleGroup {
		$t = function (string $string) {return $this->localizationController->translate($string);};

		return (new CollapsibleGroup())
			->startCollapsed()
			->setIndex(SearchOptionsEnum::class)
			->setHeader($t("Zoek formulier instellingen"))
			->setDescription($t("De instellingen voor de zoekfunctie"))
			->addContents(
				( new StringInput() )
					->setIndex(SearchOptionsEnum::FormTitle->value)
					->setName($t("Titel"))
					->setDescription($t("De titel van het zoekformulier"))
					->setDefaultValue($this->formTitle)
					->setPlaceholder($t("Zoek"))
					->addSetCallback(function ($value) {
						$this->formTitle = $value ?? $this->formTitle;
					})
					->addValidator(
						new Required($t("De titel voor het formulier is verplicht."))
					),
				(new BoolInput())
					->setIndex(SearchOptionsEnum::AskTitle->value)
					->setName($t("Zoek op titel"))
					->setDescription($t("Toon een zoekveld voor de titel van de cursus in het zoekformulier"))
					->setDefaultValue($this->askTitle)
					->addSetCallback(function ($value) {
						$this->askTitle = $value ?? $this->askTitle;
					}),
				(new BoolInput())
					->setIndex(SearchOptionsEnum::AskLocation->value)
					->setName($t("Zoek op locatie"))
					->setDescription($t("Toon de bekende locaties van de cursussen om op te zoeken in het zoekformulier"))
					->setDefaultValue($this->askLocation)
					->addSetCallback(function ($value) {
						$this->askLocation = $value ?? $this->askLocation;
					}),
				(new BoolInput())
					->setIndex(SearchOptionsEnum::AskLabels->value)
					->setName($t("Zoek op labels"))
					->setDescription($t("Toon de bekende labels van de cursussen om op te zoeken in het zoekformulier"))
					->setDefaultValue($this->askLabels)
					->addSetCallback(function ($value) {
						$this->askLabels = $value ?? $this->askLabels;
					}),
				(new BoolInput())
					->setIndex(SearchOptionsEnum::AskELearning->value)
					->setName($t("Zoek op e-learning"))
					->setDescription($t("Toon een keuze om te zoeken op of een cursus e-learning bevat in het zoekformulier"))
					->setDefaultValue($this->askELearning)
					->addSetCallback(function ($value) {
						$this->askELearning = $value ?? $this->askELearning;
					}),
				(new BoolInput())
					->setIndex(SearchOptionsEnum::AskSoob->value)
					->setName($t("Zoek op Soob"))
					->setDescription($t("Toon een keuze om te zoeken op of een cursus Soob bevat in het zoekformulier"))
					->setDefaultValue($this->askSoob)
					->addSetCallback(function ($value) {
						$this->askSoob = $value ?? $this->askSoob;
					}),
				(new BoolInput())
					->setIndex(SearchOptionsEnum::AskStap->value)
					->setName($t("Zoek op Stap"))
					->setDescription($t("Toon een keuze om te zoeken op of een cursus Stap bevat in het zoekformulier"))
					->setDefaultValue($this->askStap)
					->addSetCallback(function ($value) {
						$this->askStap = $value ?? $this->askStap;
					}),
				(new BoolInput())
					->setIndex(SearchOptionsEnum::AskCode95->value)
					->setName($t("Zoek op Code95"))
					->setDescription($t("Toon een keuze om te zoeken op of een cursus Code95 bevat in het zoekformulier"))
					->setDefaultValue($this->askCode95)
					->addSetCallback(function ($value) {
						$this->askCode95 = $value ?? $this->askCode95;
					}),
				$redirectPageQuestion = (new SelectionInput(new IntType()))
					->setIndex(SearchOptionsEnum::PageToSendTo->value)
					->setName($t("Doorstuur pagina"))
					->setDescription($t("De pagina waarop de resultaten worden weergegeven"))
					->setDefaultValue($this->pageToSendTo)
					->addSetCallback(function ($value) {
						$this->pageToSendTo = $value ?? $this->pageToSendTo;
					})
					->setOptions([
						["value" => 0, "label" => "Deze Pagina (niet doorsturen)"],
						...$this->getPagesAsOptions()
					]),
				(new BasicGroup())
					->addConditions(
						(new InputValueCondition($redirectPageQuestion))->not()->equals()->value(0)
					)->addContents(
						(new Text($t("LET OP: De doorstuur pagina moet een zoek formulier met een resultaten weergave of een cursus lijst met zoek of filter geselecteerd bevatten.")))
							->addClasses("pad-warning")
					)
			);
	}

	protected function getPagesAsOptions(): array {
		$pages = [];
		foreach ($this->urlHandler->getAllPages() as $page) {
			$pages[] = [
				"value" => $page["id"],
				"label" => $page["title"] . " (" . $page["id"] . ")",
			];
		}

		return $pages;
	}

	/**
	 * @return array{values:mixed[], subGroups:array[], subGroupAliases:string[]}
	 */
	public function getEnumMapping(): array {
		return [
			"values"          => [
				SearchOptionsEnum::AskTitle->value => &$this->askTitle,
				SearchOptionsEnum::AskLocation->value => &$this->askLocation,
				SearchOptionsEnum::AskLabels->value => &$this->askLabels,
				SearchOptionsEnum::AskELearning->value => &$this->askELearning,
				SearchOptionsEnum::AskSoob->value => &$this->askSoob,
				SearchOptionsEnum::AskStap->value => &$this->askStap,
				SearchOptionsEnum::AskCode95->value => &$this->askCode95,
				SearchOptionsEnum::PageToSendTo->value => &$this->pageToSendTo,
				SearchOptionsEnum::FormTitle->value => &$this->formTitle,
			],
			"subGroups"       => [],
			"subGroupAliases" => []
		];
	}

	public function isAskTitle(): bool {
		return $this->askTitle;
	}

	public function isAskLocation(): bool {
		return $this->askLocation;
	}

	public function isAskLabels(): bool {
		return $this->askLabels;
	}

	public function isAskELearning(): bool {
		return $this->askELearning;
	}

	public function isAskSoob(): bool {
		return $this->askSoob;
	}

	public function isAskStap(): bool {
		return $this->askStap;
	}

	public function isAskCode95(): bool {
		return $this->askCode95;
	}

	public function getPageToSendTo(): int {
		return $this->pageToSendTo;
	}

	public function getFormTitle(): string {
		return $this->formTitle;
	}
}