<?php

namespace Planaday\Config\Booking\Voucher;

use Planaday\Config\BasicEnumMappedSetting;
use Planaday\Config\BasicSettingsLog;
use Planaday\Config\EnumMappedSettings;
use Planaday\Config\FormGroupable;
use Planaday\Config\SettingsLoader;
use Planaday\Config\SettingsWithForm;
use Planaday\Config\SettingsWithUsageLog;
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\NumberInput;
use Planaday\Utility\FormBuilder\InputFields\StringInput;
use Planaday\Utility\FormBuilder\Structure;
use Planaday\Utility\FormBuilder\Structures\BasicGroup;
use Planaday\Utility\FormBuilder\Structures\CollapsibleGroup;
use Planaday\Utility\FormBuilder\Validators\Required;

#[Scoped]
class VoucherSettings implements EnumMappedSettings, SettingsWithForm, SettingsWithUsageLog {
	use FormGroupable;
	use BasicEnumMappedSetting;
	use BasicSettingsLog;

	protected bool $showVoucherAlmostExpiredMessage = false;
	protected string $voucherAlmostExpiredMessage = "Let op: Deze kortingscode vervalt binnenkort!";
	protected int $voucherAlmostExpiredThreshold = 2;

	protected bool $showVoucherAlmostUsedUpMessage = false;
	protected string $voucherAlmostUsedUpMessage = "Let op: Deze kortingscode is bijna op!";
	protected int $voucherAlmostUsedUpThreshold = 5;

	public function __construct(
		protected LocalizationController $localizationController,
		protected SettingsLoader $settingsDatabase
	) {
		$this->settingsDatabase->reloadData($this, VoucherSettingsEnum::class );
	}

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

		return (new CollapsibleGroup())
			->setIndex(VoucherSettingsEnum::class)
			->setHeader($t("Kortingscodes"))
			->setDescription($t("Instellingen over het gebruik van kortingscodes"))
			->addContents(
				( new CollapsibleGroup() )
					->setHeader($t("Bijna verlopen melding"))
					->setDescription($t("Toon een bijna verlopen melding"))
					->addContents(
						$showVoucherAlmostExpiredMessage = (new BoolInput())
							->setIndex( VoucherSettingsEnum::ShowVoucherAlmostExpiredMessage->value )
							->setName( $t( "Toon melding bijna verlopen?" ) )
							->setDescription($t("Toon een instelbare melding als de gebruikte kortingscode bijna verlopen is"))
							->setDefaultValue( $this->showVoucherAlmostExpiredMessage )
							->addSetCallback( function ( $value ) {
								$this->showVoucherAlmostExpiredMessage = $value ?? $this->showVoucherAlmostExpiredMessage;
							}),
						(new BasicGroup())
							->addConditions(
								(new InputValueCondition($showVoucherAlmostExpiredMessage))->equals()->value(true)
							)->addContents(
								( new StringInput() )
									->setIndex( VoucherSettingsEnum::VoucherAlmostExpiredMessage->value )
									->setName( $t( "Bijna verlopen melding" ) )
									->setDescription($t("Deze melding wordt getoond als de gebruikte kortingscode bijna verlopen is"))
									->setDefaultValue( $this->voucherAlmostExpiredMessage )
									->addSetCallback( function ( $value ) {
										$this->voucherAlmostExpiredMessage = $value ?? $this->voucherAlmostExpiredMessage;
									})
									->addValidator(
										new Required($t("Bijna verlopen melding is verplicht als deze getoond moet worden"))
									),
								( new NumberInput() )
									->setIndex( VoucherSettingsEnum::VoucherAlmostExpiredThreshold->value )
									->setName( $t( "Bijna verlopen dagen grens" ) )
									->setDescription($t("Vanaf hoeveel dagen beschikbaar geld de kortingscode als bijna verlopen."))
									->setDefaultValue( $this->voucherAlmostExpiredThreshold )
									->addSetCallback( function ( $value ) {
										$this->voucherAlmostExpiredThreshold = $value ?? $this->voucherAlmostExpiredThreshold;
									})
									->setMin(1)
									->addValidator(
										new Required($t("Bijna verlopen dagen is verplicht als de melding getoond moet worden"))
									)
							)
					),
				(new CollapsibleGroup())
					->setHeader($t("Bijna op melding"))
					->setDescription($t("Toon een bijna op melding"))
					->addContents(
						$showVoucherAlmostUsedUpMessage = (new BoolInput())
							->setIndex( VoucherSettingsEnum::ShowVoucherAlmostUsedUpMessage->value )
							->setName( $t( "Toon melding bijna op?" ) )
							->setDescription($t("Toon een instelbare melding als de gebruikte kortingscode bijna op is"))
							->setDefaultValue( $this->showVoucherAlmostUsedUpMessage )
							->addSetCallback( function ( $value ) {
								$this->showVoucherAlmostUsedUpMessage = $value ?? $this->showVoucherAlmostUsedUpMessage;
							}),
						(new BasicGroup())
							->addConditions(
								(new InputValueCondition($showVoucherAlmostUsedUpMessage))->equals()->value(true)
							)->addContents(
								( new StringInput() )
									->setIndex( VoucherSettingsEnum::VoucherAlmostUsedUpMessage->value )
									->setName( $t( "Bijna op melding" ) )
									->setDescription($t("Deze melding wordt getoond als de gebruikte kortingscode bijna op is"))
									->setDefaultValue( $this->voucherAlmostUsedUpMessage )
									->setPlaceholder( $t( "Let op: Deze kortingscode is bijna op!" ) )
									->addSetCallback( function ( $value ) {
										$this->voucherAlmostUsedUpMessage = $value ?? $this->voucherAlmostUsedUpMessage;
									})
									->addValidator(
										new Required($t("Bijna op melding is verplicht als deze getoond moet worden"))
									),
								( new NumberInput() )
									->setIndex( VoucherSettingsEnum::VoucherAlmostUsedUpThreshold->value )
									->setName( $t( "Bijna op grens" ) )
									->setDescription($t("Vanaf hoeveel beschikbaar geld de kortingscode als bijna op."))
									->setDefaultValue( $this->voucherAlmostUsedUpThreshold )
									->addSetCallback( function ( $value ) {
										$this->voucherAlmostUsedUpThreshold = $value ?? $this->voucherAlmostUsedUpThreshold;
									})
									->setMin(1)
									->addValidator(
										new Required($t("Bijna op grens is verplicht als de melding getoond moet worden"))
									)
							)
					)
			);
	}

	public function getEnumMapping(): array {
		return [
			"values" => [
				VoucherSettingsEnum::ShowVoucherAlmostExpiredMessage->value => &$this->showVoucherAlmostExpiredMessage,
				VoucherSettingsEnum::VoucherAlmostExpiredMessage->value => &$this->voucherAlmostExpiredMessage,
				VoucherSettingsEnum::VoucherAlmostExpiredThreshold->value => &$this->voucherAlmostExpiredThreshold,

				VoucherSettingsEnum::ShowVoucherAlmostUsedUpMessage->value => &$this->showVoucherAlmostUsedUpMessage,
				VoucherSettingsEnum::VoucherAlmostUsedUpMessage->value => &$this->voucherAlmostUsedUpMessage,
				VoucherSettingsEnum::VoucherAlmostUsedUpThreshold->value => &$this->voucherAlmostUsedUpThreshold,
			],
			"subGroups"       => [],
			"subGroupAliases" => []
		];
	}

	public function isShowVoucherAlmostExpiredMessage(): bool {
		$this->logUse( VoucherSettingsEnum::ShowVoucherAlmostExpiredMessage );
		return $this->showVoucherAlmostExpiredMessage;
	}

	public function getVoucherAlmostExpiredMessage(): string {
		$this->logUse( VoucherSettingsEnum::VoucherAlmostExpiredMessage );
		return $this->voucherAlmostExpiredMessage;
	}

	public function getVoucherAlmostExpiredThreshold(): int {
		$this->logUse( VoucherSettingsEnum::VoucherAlmostExpiredThreshold );
		return $this->voucherAlmostExpiredThreshold;
	}

	public function isShowVoucherAlmostUsedUpMessage(): bool {
		$this->logUse( VoucherSettingsEnum::ShowVoucherAlmostUsedUpMessage );
		return $this->showVoucherAlmostUsedUpMessage;
	}

	public function getVoucherAlmostUsedUpMessage(): string {
		$this->logUse( VoucherSettingsEnum::VoucherAlmostUsedUpMessage );
		return $this->voucherAlmostUsedUpMessage;
	}

	public function getVoucherAlmostUsedUpThreshold(): int {
		$this->logUse( VoucherSettingsEnum::VoucherAlmostUsedUpThreshold );
		return $this->voucherAlmostUsedUpThreshold;
	}
}