<?php

namespace Planaday\Entities\Booking\Form\DayParts;

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\Structures\BasicGroup;
use Planaday\Utility\FormBuilder\Structures\CollapsibleGroup;
use Planaday\Utility\FormBuilder\Validators\Required;

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

	protected bool $showPrice = true;
	protected bool $showBothWithAndWithoutTaxPrice = false;
	protected bool $onlyShowPriceIfPerDayPart = true;
	protected bool $showLocation = true;
	protected bool $showDate = true;
	protected bool $showTime = true;
	protected string $title = 'Dagdelen selectie';

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

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

		return ( new CollapsibleGroup() )
			->startCollapsed()
			->setIndex( DayPartsSettingsEnum::class )
			->setHeader($t("Dagdelen selectie"))
			->setDescription($t("Instellingen over de dagdelen selectie als een cursus daar een optie in geeft."))
			->addContents(
				(new StringInput())
					->setIndex( DayPartsSettingsEnum::Title->value )
					->setName( $t( "Titel dagdelen selectie" ) )
					->setDescription( $t( "De titel van de dagdelen selectie." ) )
					->setDefaultValue( $this->title )
					->addSetCallback( function ( $value ) {
						$this->title = $value ?? $this->title;
					})
					->addValidator(
						new Required($t("Titel dagdelen selectie is verplicht"))
					),
				(new BoolInput())
					->setIndex( DayPartsSettingsEnum::ShowDate->value )
					->setName( $t( "Toon datum dagdeel" ) )
					->setDescription( $t( "Toon bij elk dagdeel de datum van dit dagdeel." ) )
					->setDefaultValue( $this->showDate )
					->addSetCallback( function ( $value ) {
						$this->showDate = $value ?? $this->showDate;
					}),
				(new BoolInput())
					->setIndex( DayPartsSettingsEnum::ShowTime->value )
					->setName( $t( "Toon tijd dagdeel" ) )
					->setDescription( $t( "Toon bij elk dagdeel het tijdstip van dit dagdeel." ) )
					->setDefaultValue( $this->showTime )
					->addSetCallback( function ( $value ) {
						$this->showTime = $value ?? $this->showTime;
					}),
				(new BoolInput())
					->setIndex( DayPartsSettingsEnum::ShowLocation->value )
					->setName( $t( "Toon locatie dagdeel" ) )
					->setDescription( $t( "Toon bij elk dagdeel de locatie van dit dagdeel." ) )
					->setDefaultValue( $this->showLocation )
					->addSetCallback( function ( $value ) {
						$this->showLocation = $value ?? $this->showLocation;
					}),
				$showPrice = ( new BoolInput() )
					->setIndex(DayPartsSettingsEnum::ShowPrice->value)
					->setName( $t( "Toon prijs dagdeel" ) )
					->setDescription( $t( "Toon bij de dagdelen de prijs van het dagdeel." ) )
					->setDefaultValue( $this->showPrice )
					->addSetCallback( function ( $value ) {
						$this->showPrice = $value ?? $this->showPrice;
					}),
				( new BasicGroup() )
					->addContents(
						( new BoolInput() )
							->setIndex( DayPartsSettingsEnum::ShowPriceWithAndWithoutTax->value )
							->setName( $t( "Toon prijs met en zonder BTW" ) )
							->setDescription( $t( "Toon bij de dagdelen de prijs met en zonder BTW. Anders " .
							                      "wordt alleen de standaardprijs getoond." ) )
							->setDefaultValue( $this->showBothWithAndWithoutTaxPrice )
							->addSetCallback( function ( $value ) {
								$this->showBothWithAndWithoutTaxPrice = $value ?? $this->showBothWithAndWithoutTaxPrice;
							}),
						( new BoolInput() )
							->setIndex( DayPartsSettingsEnum::OnlyShowPriceIfPerDayPart->value )
							->setName( $t( "Toon prijs alleen als prijs per dagdeel is" ) )
							->setDescription( $t( "Toon de prijs alleen als de prijs van de cursus wordt bepaald door " .
							                      "de geselecteerde dagdelen." ) )
							->setDefaultValue( $this->onlyShowPriceIfPerDayPart )
							->addSetCallback( function ( $value ) {
								$this->onlyShowPriceIfPerDayPart = $value ?? $this->onlyShowPriceIfPerDayPart;
							})
					)->addConditions(
						(new InputValueCondition($showPrice))->equals()->value(true)
					)->addClasses("pad-subgroup"),
			);
	}

	/**
	 * @return array{values:mixed[], subGroups:array[], subGroupAliases:string[]}
	 */
	public function getEnumMapping(): array {
		return [
			"values"          => [
				DayPartsSettingsEnum::Title->value => &$this->title,
				DayPartsSettingsEnum::ShowDate->value => &$this->showDate,
				DayPartsSettingsEnum::ShowTime->value => &$this->showTime,
				DayPartsSettingsEnum::ShowLocation->value => &$this->showLocation,
				DayPartsSettingsEnum::ShowPrice->value => &$this->showPrice,
				DayPartsSettingsEnum::ShowPriceWithAndWithoutTax->value => &$this->showBothWithAndWithoutTaxPrice,
				DayPartsSettingsEnum::OnlyShowPriceIfPerDayPart->value => &$this->onlyShowPriceIfPerDayPart,
			],
			"subGroups"       => [],
			"subGroupAliases" => []
		];
	}

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

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

	public function isOnlyShowPriceIfPerDayPart(): bool {
		return $this->onlyShowPriceIfPerDayPart;
	}

	public function isShowLocation(): bool {
		return $this->showLocation;
	}

	public function isShowDate(): bool {
		return $this->showDate;
	}

	public function isShowTime(): bool {
		return $this->showTime;
	}

	public function getTitle(): string {
		return $this->title;
	}
}