<?php

namespace Planaday\Config\Course\General;

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\InputFields\BoolInput;
use Planaday\Utility\FormBuilder\InputFields\StringInput;
use Planaday\Utility\FormBuilder\LayoutItems\Text;
use Planaday\Utility\FormBuilder\Structures\BasicGroup;
use Planaday\Utility\FormBuilder\Validators\Required;

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

	protected string $dayPartText = 'dagen';
	protected bool $includeOptionInCount = true;
	protected bool $skipELearningOnly = true;
	protected bool $eLearningCountsAsStart = true;
	protected bool $includeELearningDayParts = false;

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

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

		return ( new BasicGroup() )
			->setIndex( GeneralOptionsEnum::class )
			->addContents(
				new Text($t('Algemene instellingen voor cursussen')),
				( new StringInput() )
					->setIndex( GeneralOptionsEnum::DAY_PART_TEXT->value )
					->setName( $t("Naam die wordt getoond bij 'dagdelen'") )
					->setDescription( $t("Bepaal zelf hoe de dagdelen worden genoemd. Bijvoorbeeld: 'dagen' of 'dagdelen'."))
					->setDefaultValue( $this->dayPartText )
					->setPlaceholder( $t('dagen'))
					->addSetCallback( function ( $value ) {
						$this->dayPartText = $value ?? $this->dayPartText;
					})
					->addValidator(
						new Required($t('Dit veld is verplicht'))
					),
				( new BoolInput() )
					->setIndex( GeneralOptionsEnum::INCLUDE_OPTION_IN_COUNT->value )
					->setName( $t("Opties meetellen") )
					->setDescription( $t("Moeten openstaande opties (van inschrijvingen) ook meegeteld worden " .
					                     "in beschikbaarheid? Zo ja, dan worden opties ook als 'bezet' meegeteld.") )
					->setDefaultValue( $this->includeOptionInCount )
					->addSetCallback( function ( $value ) {
						$this->includeOptionInCount = $value ?? $this->includeOptionInCount;
					}),
				( new BoolInput() )
					->setIndex( GeneralOptionsEnum::SKIP_E_LEARNING_ONLY->value )
					->setName( $t("Cursussen met alleen e-learning overslaan?") )
					->setDescription( $t("Moeten cursussen met alleen e-learning overgeslagen worden?") )
					->setDefaultValue( $this->skipELearningOnly )
					->addSetCallback( function ( $value ) {
						$this->skipELearningOnly = $value ?? $this->skipELearningOnly;
					}),
				( new BoolInput() )
					->setIndex( GeneralOptionsEnum::E_LEARNING_COUNTS_AS_START->value )
					->setName( $t("E-learning als start") )
					->setDescription( $t("Tellen e-learning dagdelen als de start van een cursus?") )
					->setDefaultValue( $this->eLearningCountsAsStart )
					->addSetCallback( function ( $value ) {
						$this->eLearningCountsAsStart = $value ?? $this->eLearningCountsAsStart;
					}),
				( new BoolInput() )
					->setIndex( GeneralOptionsEnum::INCLUDE_E_LEARNING_DAY_PARTS->value )
					->setName( $t("E-learning dagdelen") )
					->setDescription( $t("Moeten dagdelen met e-learning worden getoond?") )
					->setDefaultValue( $this->includeELearningDayParts )
					->addSetCallback( function ( $value ) {
						$this->includeELearningDayParts = $value ?? $this->includeELearningDayParts;
					})
			);
	}

	/**
	 * @return array{values:mixed[], subGroups:array[], subGroupAliases:string[]}
	 */
	public function getEnumMapping(): array {
		return [
			"values"          => [
				GeneralOptionsEnum::DAY_PART_TEXT->value => &$this->dayPartText,
				GeneralOptionsEnum::INCLUDE_OPTION_IN_COUNT->value => &$this->includeOptionInCount,
				GeneralOptionsEnum::SKIP_E_LEARNING_ONLY->value => &$this->skipELearningOnly,
				GeneralOptionsEnum::E_LEARNING_COUNTS_AS_START->value => &$this->eLearningCountsAsStart,
				GeneralOptionsEnum::INCLUDE_E_LEARNING_DAY_PARTS->value => &$this->includeELearningDayParts,
			],
			"subGroups"       => [],
			"subGroupAliases" => []
		];
	}

	public function getDayPartText(): string {
		$this->logUse( GeneralOptionsEnum::DAY_PART_TEXT );
		return $this->dayPartText;
	}

	public function isIncludeOptionInCount(): bool {
		$this->logUse( GeneralOptionsEnum::INCLUDE_OPTION_IN_COUNT );
		return $this->includeOptionInCount;
	}

	public function isSkipELearningOnly(): bool {
		$this->logUse( GeneralOptionsEnum::SKIP_E_LEARNING_ONLY );
		return $this->skipELearningOnly;
	}

	public function isELearningCountsAsStart(): bool {
		$this->logUse( GeneralOptionsEnum::E_LEARNING_COUNTS_AS_START );
		return $this->eLearningCountsAsStart;
	}

	public function isIncludeELearningDayParts(): bool {
		$this->logUse( GeneralOptionsEnum::INCLUDE_E_LEARNING_DAY_PARTS );
		return $this->includeELearningDayParts;
	}
}