<?php

namespace Planaday\Entities\Booking\Form\Materials;

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\Utility\DependencyInjection\Attributes\Scoped;
use Planaday\Utility\FormBuilder\Conditions\InputValueCondition;
use Planaday\Utility\FormBuilder\InputFields\BoolInput;
use Planaday\Utility\FormBuilder\InputFields\StringInput;
use Planaday\Utility\FormBuilder\InputFields\TextEditorInput;
use Planaday\Utility\FormBuilder\Structures\BasicGroup;
use Planaday\Utility\FormBuilder\Structures\CollapsibleGroup;
use Planaday\Utility\FormBuilder\Validators\Required;

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

	protected bool $askMaterialsBookingForm = false;
	protected bool $showDescriptionMaterials = false;
	protected bool $showPrice = true;
	protected bool $showBothWithAndWithoutTaxPrice = false;
	protected string $materialsFormTitle = "Welke opties zou je willen meebestellen?";
	protected ?string $materialsFormDescription = null;

	public function __construct(
		protected LocalizationController $translator,
		SettingsLoader $settingsLoader
	) {
		$settingsLoader->reloadData($this, MaterialSettingsEnum::class);
	}

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

		return ( new CollapsibleGroup() )
			->startCollapsed()
			->setIndex( MaterialSettingsEnum::class )
			->setHeader($t("Materialen"))
			->setDescription($t("Instellingen over de materialen die weergeven kunnen worden bij het boeken van een cursus."))
			->addContents(
				( $askMaterialsBookingForm = (new BoolInput())
					->setIndex( MaterialSettingsEnum::ShowMaterials->value )
					->setName( $t( "Toon materialen in boekingsformulier" ) )
					->setDescription( $t( "Toon materialen indien er materialen in een dagdeel bij een cursus " .
					                      "gekoppeld zijn en beschikbaar zijn voor de api. Dan kan de bezoeker deze " .
					                      "meteen meebestellen.'" ) )
					->setDefaultValue( $this->askMaterialsBookingForm )
					->addSetCallback( function ( $value ) {
						$this->askMaterialsBookingForm = $value ?? $this->askMaterialsBookingForm;
					}) ),
				( new BasicGroup() )
					->addConditions(
						(new InputValueCondition($askMaterialsBookingForm))->equals()->value(true)
					)->addContents(
						( new StringInput() )
							->setIndex( MaterialSettingsEnum::FormTitle->value )
							->setName( $t( "Titel in formulier" ) )
							->setDescription( $t( "Welke titel moet in het formulier getoond worden?" ) )
							->setDefaultValue( $this->materialsFormTitle )
							->addSetCallback( function ( $value ) {
								$this->materialsFormTitle = $value ?? $this->materialsFormTitle;
							})
							->addValidator(
								new Required($t("Titel in het formulier is verplicht"))
							),
						( new TextEditorInput() )
							->setIndex( MaterialSettingsEnum::FormDescription->value )
							->setName( $t( "Omschrijving in formulier" ) )
							->setDescription( $t( "Welke omschrijving over de materialen moet in het formulier getoond worden?" ) )
							->setDefaultValue( $this->materialsFormDescription )
							->addSetCallback( function ( $value ) {
								$this->materialsFormDescription = $value ?? $this->materialsFormDescription;
							}),
						(new BoolInput())
							->setIndex( MaterialSettingsEnum::ShowMaterialDescription->value )
							->setName( $t( "Toon omschrijving van materiaal" ) )
							->setDescription( $t( "Toon bij de materialen een omschrijving van het materiaal." ) )
							->setDefaultValue( $this->showDescriptionMaterials )
							->addSetCallback( function ( $value ) {
								$this->showDescriptionMaterials = $value ?? $this->showDescriptionMaterials;
							}),
						$showPrice = ( new BoolInput() )
							->setIndex(MaterialSettingsEnum::ShowMaterialPrice->value)
							->setName( $t( "Toon prijs van materiaal" ) )
							->setDescription( $t( "Toon bij de materialen de prijs van het materiaal." ) )
							->setDefaultValue( $this->showPrice )
							->addSetCallback( function ( $value ) {
								$this->showPrice = $value ?? $this->showPrice;
							}),
						( new BoolInput() )
							->setIndex( MaterialSettingsEnum::ShowPriceIncludingAndExcludingTax->value )
							->setName( $t( "Toon prijs met en zonder BTW" ) )
							->setDescription( $t( "Toon bij de materialen de prijs met en zonder BTW. Anders " .
							                      "wordt alleen de standaardprijs getoond." ) )
							->setDefaultValue( $this->showBothWithAndWithoutTaxPrice )
							->addSetCallback( function ( $value ) {
								$this->showBothWithAndWithoutTaxPrice = $value ?? $this->showBothWithAndWithoutTaxPrice;
							})->addConditions(
								(new InputValueCondition($showPrice))->equals()->value(true)
							),
					)
			);
	}

	/**
	 * @return array{values:mixed[], subGroups:array[], subGroupAliases:string[]}
	 */
	public function getEnumMapping(): array {
		return [
			"values"          => [
				MaterialSettingsEnum::ShowMaterials->value => &$this->askMaterialsBookingForm,
				MaterialSettingsEnum::ShowMaterialDescription->value => &$this->showDescriptionMaterials,
				MaterialSettingsEnum::ShowMaterialPrice->value => &$this->showPrice,
				MaterialSettingsEnum::ShowPriceIncludingAndExcludingTax->value => &$this->showBothWithAndWithoutTaxPrice,
				MaterialSettingsEnum::FormTitle->value => &$this->materialsFormTitle,
				MaterialSettingsEnum::FormDescription->value => &$this->materialsFormDescription,
			],
			"subGroups"       => [],
			"subGroupAliases" => []
		];
	}

	public function isAskMaterialsBookingForm(): bool {
		return $this->askMaterialsBookingForm;
	}

	public function isShowDescriptionMaterials(): bool {
		return $this->showDescriptionMaterials;
	}

	public function isShowPrice(): bool {
		return $this->showPrice;
	}

	public function isShowBothWithAndWithoutTaxPrice(): bool {
		return $this->showBothWithAndWithoutTaxPrice;
	}

	public function getMaterialsFormTitle(): string {
		return $this->materialsFormTitle;
	}

	public function getMaterialsFormDescription(): ?string {
		return $this->materialsFormDescription;
	}
}