<?php

namespace Planaday\Config\Booking\Submission\Redirecting;

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

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

	const NO_REDIRECT_SUCCESS_TEXT_DEFAULT =
		"<p>Hallo {naam},</p>" .
		"<p>Bedankt voor je aanmelding voor de cursus: {cursus} met startdatum: {startdatum}.<br/>" .
		"Zodra wij deze hebben verwerkt krijg je nog een definitieve bevestiging per e-mail.</p>";

	const NO_REDIRECT_FAILURE_TEXT_DEFAULT =
		"<p>Hallo {naam},</p>" .
		"<p>Bedankt voor je aanmelding voor de cursus: {cursus} met startdatum: {startdatum}.<br/>" .
		"Om een of andere reden is de boeking niet gelukt.</p>" .
		"<p>Neem voor de zekerheid contact met ons op zodat wij dit kunnen nakijken.</p>";

	protected bool $redirectAfterSuccess = false;
	protected int $successPage = 0;
	protected string $successText = self::NO_REDIRECT_SUCCESS_TEXT_DEFAULT;
	protected bool $redirectAfterFailure = false;
	protected int $failurePage = 0;
	protected string $failureText = self::NO_REDIRECT_FAILURE_TEXT_DEFAULT;

	public function __construct(
		protected LocalizationController $translator,
		protected SettingsLoader $settingsDatabase,
		protected UrlHandler $urlHandler,
	) {
		$this->settingsDatabase->reloadData($this, RedirectOptionsEnum::class );
	}

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

		$allPages = $this->urlHandler->getAllPages();
		$pageOptions = [
			[
				"value" => 0,
				"label" => $t("selecteer een pagina")
			]
		];
		foreach ( $allPages as $page ) {
			$pageOptions[] = [
				"value" => $page["id"],
				"label" => $page["title"] . " (" . $page["id"] . ")"
			];
		}

		return ( new BasicGroup() )
			->setIndex( RedirectOptionsEnum::class )
			->addContents(
				(new CollapsibleGroup())
					->setHeader($t("Succesvolle boeking"))
					->setDescription($t("Opties voor na een succesvolle boeking"))
					->addContents(
						$redirectAfterSuccess = ( new BoolInput() )
							->setIndex( RedirectOptionsEnum::REDIRECT_AFTER_SUCCESS->value )
							->setName( $t('Naar andere pagina sturen?') )
							->setDescription( $t('Wilt u dat de cursist na het succesvol indienen van een ' .
							                     'boeking naar een andere pagina wordt gestuurd?') )
							->setDefaultValue( $this->redirectAfterSuccess )
							->addSetCallback( function ( $value ) {
								$this->redirectAfterSuccess = $value ?? $this->redirectAfterSuccess;
							}),
						( new BasicGroup() )
							->addConditions(
								( new InputValueCondition($redirectAfterSuccess) )->equals()->value(true)
							)->addContents(
								( new SelectionInput(new IntType()) )
									->setIndex( RedirectOptionsEnum::REDIRECT_SUCCESS_PAGE->value )
									->setName( $t('Pagina na succesvol indienen') )
									->setDescription( $t('Welke pagina wilt u dat de cursist na het succesvol ' .
									                     'indienen van een boeking naar wordt gestuurd?') )
									->setDefaultValue( $this->successPage )
									->addSetCallback( function ( $value ) {
										$this->successPage = $value ?? $this->successPage;
									})
									->setOptions( $pageOptions )
									->addValidator(
										(new Required($t('De pagina is verplicht als je wilt doorsturen')))->zeroIsInvalid()
									)
							),
						( new BasicGroup() )
							->addConditions(
								( new InputValueCondition($redirectAfterSuccess) )->equals()->value(false)
							)->addContents(
								( new TextEditorInput() )
									->setIndex( RedirectOptionsEnum::NO_REDIRECT_SUCCESS_TEXT->value )
									->setName( $t('Bedankt tekst na boeking') )
									->setDescription( $t('Tekst die op de pagina wordt getoond als een boeking ' .
									                     'door een deelnemer is gelukt. Gebruik de planaday knop in de' .
									                     ' editor om de tekst te vervangen door de juiste dynamische waarden.'))
									->setDefaultValue( $this->successText )
									->addSetCallback( function ( $value ) {
										$this->successText = $value ?? $this->successText;
									})
									->addValidator(
										new Required($t('Een tekst is verplicht als er niet wordt doorgestuurd'))
									)
									->setButtonLayout([
										"Cursus" => [
											"naam" => "{cursus}",
											"code" => "{cursuscode}",
											"startdatum" => "{startdatum}",
										],
										"Cursist" => [
											"volledige naam" => "{naam}",
											"voornaam" => "{voornaam}",
											"achternaam" => "{achternaam}",
										],
										"Boeking" => [
											"id" => "{padboekingid}",
										],
										"Transactie (indien betaling actief)" => [
											"id" => "{idealtransactieid}",
											"bedrag" => "{bedrag}",
											"betaald melding" => "{betaald}",
										],
										"Website naam/titel" => "{website}",
									])
							)
					),
				(new CollapsibleGroup())
					->setHeader($t("Niet succesvolle boeking"))
					->setDescription($t("Opties voor na een niet succesvolle boeking"))
					->addContents(
						$redirectAfterFailure = ( new BoolInput() )
							->setIndex( RedirectOptionsEnum::REDIRECT_AFTER_FAILURE->value )
							->setName( $t('Naar andere pagina sturen?') )
							->setDescription( $t('Wilt u dat de cursist na het niet succesvol indienen van een ' .
							                     'boeking naar een andere pagina wordt gestuurd?') )
							->setDefaultValue( $this->redirectAfterFailure )
							->addSetCallback( function ( $value ) {
								$this->redirectAfterFailure = $value ?? $this->redirectAfterFailure;
							}),
						( new BasicGroup() )
							->addConditions(
								( new InputValueCondition($redirectAfterFailure) )->equals()->value(true)
							)->addContents(
								( new SelectionInput(new IntType()) )
									->setIndex( RedirectOptionsEnum::REDIRECT_FAILURE_PAGE->value )
									->setName( $t('Pagina na niet succesvol indienen') )
									->setDescription( $t('Welke pagina wilt u dat de cursist na het niet succesvol ' .
									                     'indienen van een boeking naar wordt gestuurd?') )
									->setDefaultValue( $this->failurePage )
									->addSetCallback( function ( $value ) {
										$this->failurePage = $value ?? $this->failurePage;
									})
									->setOptions( $pageOptions )
									->addValidator(
										(new Required($t('De pagina is verplicht als je wilt doorsturen')))->zeroIsInvalid()
									)
							),
						( new BasicGroup() )
							->addConditions(
								( new InputValueCondition($redirectAfterFailure) )->equals()->value(false)
							)->addContents(
								( new TextEditorInput() )
									->setIndex( RedirectOptionsEnum::NO_REDIRECT_FAILURE_TEXT->value )
									->setName( $t('Bedankt tekst na boeking') )
									->setDescription($t('Tekst die op de pagina wordt getoond als een boeking ' .
									                    'door een deelnemer niet is gelukt. Gebruik de planaday knop in de' .
									                    ' editor om de tekst te vervangen door de juiste dynamische waarden.'))
									->setDefaultValue( $this->failureText )
									->addSetCallback( function ( $value ) {
										$this->failureText = $value ?? $this->failureText;
									})
									->addValidator(
										new Required($t('Een tekst is verplicht als er niet wordt doorgestuurd'))
									)
									->setButtonLayout([
										"Cursus" => [
											"naam" => "{cursus}",
											"code" => "{cursuscode}",
											"startdatum" => "{startdatum}",
										],
										"Cursist" => [
											"volledige naam" => "{naam}",
											"voornaam" => "{voornaam}",
											"achternaam" => "{achternaam}",
										],
										"Website naam/titel" => "{website}",
									])
							)
					)
			);
	}

	/**
	 * @return array{values:mixed[], subGroups:array[], subGroupAliases:string[]}
	 */
	public function getEnumMapping(): array {
		return [
			"values"          => [
				RedirectOptionsEnum::NO_REDIRECT_FAILURE_TEXT->value => &$this->failureText,
				RedirectOptionsEnum::NO_REDIRECT_SUCCESS_TEXT->value => &$this->successText,
				RedirectOptionsEnum::REDIRECT_AFTER_FAILURE->value => &$this->redirectAfterFailure,
				RedirectOptionsEnum::REDIRECT_AFTER_SUCCESS->value => &$this->redirectAfterSuccess,
				RedirectOptionsEnum::REDIRECT_FAILURE_PAGE->value => &$this->failurePage,
				RedirectOptionsEnum::REDIRECT_SUCCESS_PAGE->value => &$this->successPage,
			],
			"subGroups"       => [],
			"subGroupAliases" => []
		];
	}

	public function isRedirectAfterSuccess(): bool {
		$this->logUse( RedirectOptionsEnum::REDIRECT_AFTER_SUCCESS );
		return $this->redirectAfterSuccess;
	}

	public function getSuccessPage(): int {
		$this->logUse( RedirectOptionsEnum::REDIRECT_SUCCESS_PAGE );
		return $this->successPage;
	}

	public function getSuccessText(): string {
		$this->logUse( RedirectOptionsEnum::NO_REDIRECT_SUCCESS_TEXT );
		return $this->successText;
	}

	public function isRedirectAfterFailure(): bool {
		$this->logUse( RedirectOptionsEnum::REDIRECT_AFTER_FAILURE );
		return $this->redirectAfterFailure;
	}

	public function getFailurePage(): int {
		$this->logUse( RedirectOptionsEnum::REDIRECT_FAILURE_PAGE );
		return $this->failurePage;
	}

	public function getFailureText(): string {
		$this->logUse( RedirectOptionsEnum::NO_REDIRECT_FAILURE_TEXT );
		return $this->failureText;
	}
}