<?php

namespace Planaday\Config\Booking\Submission\Mail;

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

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

	protected const STUDENT_MAIL_CONTENTS_DEFAULT =
		"<p>Hallo {naam},</p>" .
		"<p>Er is een aanmelding binnengekomen voor de cursus: {cursus} met startdatum: {startdatum}.<br/>" .
		"Deze aanmelding voor de cursus/opleiding is bij ons binnengekomen en moet nog worden verwerkt.<br/>" .
		"Zodra wij deze hebben verwerkt krijg je nog een definitieve bevestiging per E-mail.</p>" .
		"<p>Met vriendelijke groet,</p>" .
		"<p>-- <br/>" .
		"{website}</p>";

	protected bool $studentToggle = false;
	protected string $studentContents = self::STUDENT_MAIL_CONTENTS_DEFAULT;
	protected bool $companyToggle = false;
	protected ?string $companyContents = null;
	protected bool $adminToggle = false;
	protected ?string $adminAddress = null;

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

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

		return ( new BasicGroup() )
			->setIndex( MailOptionsEnum::class )
			->addContents(
				( new CollapsibleGroup() )
					->setHeader( $t( "Cursist mail" ) )
					->setDescription( $t( "Stuur een mail naar de cursisten van de boeking." ) )
					->addContents(
						$studentToggle = ( new BoolInput() )
							->setIndex( MailOptionsEnum::MAIL_STUDENT->value )
							->setName( $t( "Cursist mailen?" ) )
							->setDescription( $t( "Moet cursist een mail krijgen dat aanmelding wel/niet is gelukt?" ) )
							->setDefaultValue( $this->studentToggle )
							->addSetCallback( function ( $value ) {
								$this->studentToggle = $value ?? $this->studentToggle;
							}),
						( new BasicGroup() )
							->addConditions(
								( new InputValueCondition($studentToggle) )->equals()->value(true)
							)->addContents(
								( new TextEditorInput() )
									->setIndex( MailOptionsEnum::MAIL_STUDENT_CONTENTS->value )
									->setName( $t( "Mail tekst naar cursist" ) )
									->setDescription( $t( "Mail die wordt gestuurd na het boeken. Gebruik de " .
									                      "planaday knop in de editor om de tekst te vervangen door de" .
									                      " juiste dynamische waarden."))
									->setDefaultValue( $this->studentContents )
									->addSetCallback( function ( $value ) {
										$this->studentContents = $value ?? $this->studentContents;
									})
									->addValidator(
										new Required($t( "Mail inhoud is verplicht als een mail moet worden gestuurd." ))
									)
									->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( "Bedrijf mailen?" ) )
					->setDescription( $t( "Stuur een mail naar de bedrijfsbeheerder van de boeking." ) )
					->addContents(
						$companyToggle = ( new BoolInput() )
							->setIndex( MailOptionsEnum::MAIL_COMPANY->value )
							->setName( $t( "Bedrijfsbeheerder mailen?" ) )
							->setDescription( $t( "Moet het bedrijf een mail krijgen dat aanmelding wel/niet is gelukt?" ) )
							->setDefaultValue( $this->companyToggle )
							->addSetCallback( function ( $value ) {
								$this->companyToggle = $value ?? $this->companyToggle;
							}),
						( new BasicGroup() )
							->addConditions(
								( new InputValueCondition($companyToggle) )->equals()->value(true)
							)->addContents(
								( new TextEditorInput() )
									->setIndex( MailOptionsEnum::MAIL_COMPANY_CONTENTS->value )
									->setName( $t( "Mail tekst naar bedrijf" ) )
									->setDescription($t( "Mail die wordt gestuurd na het boeken. Gebruik de " .
									                     "planaday knop in de editor om de tekst te vervangen door de" .
									                     " juiste dynamische waarden."))
									->setDefaultValue( $this->companyContents )
									->addSetCallback( function ( $value ) {
										$this->companyContents = $value ?? $this->companyContents;
									})
									->addValidator(
										new Required($t( "Mail inhoud is verplicht als een mail moet worden gestuurd." ))
									)
									->setButtonLayout([
										"Cursus" => [
											"naam" => "{cursus}",
											"code" => "{cursuscode}",
											"startdatum" => "{startdatum}",
										],
										"Cursisten lijst" => "{studenteninfo}",
										"Bedrijfsnaam" => "{bedrijfsnaam}",
										"Boeking" => [
											"id" => "{padboekingid}",
										],
										"Transactie (indien betaling actief)" => [
											"id" => "{idealtransactieid}",
											"bedrag" => "{bedrag}",
											"betaald melding" => "{betaald}",
											"betaling info" => "{betaalinfo}",
										],
										"Website naam/titel" => "{website}",
									])
							)
					),
				( new CollapsibleGroup() )
					->setHeader( $t( "Admin mailen?" ) )
					->setDescription( $t( "Stuur een mail naar de admin van de website." ) )
					->addContents(
						$adminToggle = ( new BoolInput() )
							->setIndex( MailOptionsEnum::MAIL_ADMIN->value )
							->setName( $t( "Admin mailen?" ) )
							->setDescription( $t( "Moet de admin een mail krijgen dat aanmelding wel/niet is gelukt?" ) )
							->setDefaultValue( $this->adminToggle )
							->addSetCallback( function ( $value ) {
								$this->adminToggle = $value ?? $this->adminToggle;
							}),
						( new BasicGroup() )
							->addConditions(
								( new InputValueCondition($adminToggle) )->equals()->value(true)
							)->addContents(
								( new StringInput() )
									->setIndex( MailOptionsEnum::ADMIN_ADDRESS->value )
									->setName( $t( "Admin mailadres" ) )
									->setDescription( $t( "Mailadres waar de admin naar moet worden gestuurd." ) )
									->setDefaultValue( $this->adminAddress )
									->addSetCallback( function ( $value ) {
										$this->adminAddress = $value ?? $this->adminAddress;
									})
									->addValidator(
										new Required($t( "Mailadres is verplicht als een mail moet worden gestuurd." )),
										new RegexValidator(
											"email",
											RegexUtility::SIMPLE_EMAIL_REGEX,
											$t( "Mailadres is niet geldig." ),
										)
									)
							)
					)
			);
	}

	/**
	 * @return array{values:mixed[], subGroups:array[], subGroupAliases:string[]}
	 */
	public function getEnumMapping(): array {
		return [
			"values"          => [
				MailOptionsEnum::MAIL_ADMIN->value => &$this->adminToggle,
				MailOptionsEnum::ADMIN_ADDRESS->value => &$this->adminAddress,
				MailOptionsEnum::MAIL_STUDENT->value => &$this->studentToggle,
				MailOptionsEnum::MAIL_STUDENT_CONTENTS->value => &$this->studentContents,
				MailOptionsEnum::MAIL_COMPANY->value => &$this->companyToggle,
				MailOptionsEnum::MAIL_COMPANY_CONTENTS->value => &$this->companyContents,
			],
			"subGroups"       => [],
			"subGroupAliases" => []
		];
	}

	public function isStudentToggle(): bool {
		$this->logUse( MailOptionsEnum::MAIL_STUDENT );
		return $this->studentToggle;
	}

	public function getStudentContents(): string {
		$this->logUse( MailOptionsEnum::MAIL_STUDENT_CONTENTS );
		return $this->studentContents;
	}

	public function isCompanyToggle(): bool {
		$this->logUse( MailOptionsEnum::MAIL_COMPANY );
		return $this->companyToggle;
	}

	public function getCompanyContents(): ?string {
		$this->logUse( MailOptionsEnum::MAIL_COMPANY_CONTENTS );
		return $this->companyContents;
	}

	public function isAdminToggle(): bool {
		$this->logUse( MailOptionsEnum::MAIL_ADMIN );
		return $this->adminToggle;
	}

	public function getAdminAddress(): ?string {
		$this->logUse( MailOptionsEnum::ADMIN_ADDRESS );
		return $this->adminAddress;
	}
}