<?php

namespace Planaday\Config\Course\Search;

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\DataTypes\IntType;
use Planaday\Utility\FormBuilder\InputFields\BoolInput;
use Planaday\Utility\FormBuilder\InputFields\RadioInput;
use Planaday\Utility\FormBuilder\LayoutItems\Text;
use Planaday\Utility\FormBuilder\Structures\BasicGroup;
use Planaday\Utility\FormBuilder\Structures\QuestionCluster;

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

	protected bool $askTitle = false;
	protected bool $askLocation = false;
	protected bool $askLabels = false;
	protected bool $askCode95 = false;
	protected bool $askSoob = false;
	protected bool $askELearning = false;
	protected bool $askStap = false;
	protected int $outputFormat = 0;

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

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

		return ( new BasicGroup() )
			->setIndex( SearchOptionsEnum::class )
			->addContents(
				new Text($t('Instellingen voor de zoek shortcode')),
				( new QuestionCluster() )
					->setIndex(null)
					->setName($t('ZoekOpties'))
					->setDescription($t('Op welke gegevens kan worden gezocht?'))
					->addContents(
						( new BoolInput() )
							->setIndex( SearchOptionsEnum::ASK_TITLE->value )
							->setName( $t("Titel") )
							->setDescription( $t("Vraag naar de titel van de cursus") )
							->setDefaultValue( $this->askTitle )
							->addSetCallback( function ( $value ) {
								$this->askTitle = $value ?? $this->askTitle;
							}),
						( new BoolInput() )
							->setIndex( SearchOptionsEnum::ASK_LOCATION->value )
							->setName( $t("Locatie") )
							->setDescription( $t("Vraag naar de locatie van de cursus") )
							->setDefaultValue( $this->askLocation )
							->addSetCallback( function ( $value ) {
								$this->askLocation = $value ?? $this->askLocation;
							}),
						( new BoolInput() )
							->setIndex( SearchOptionsEnum::ASK_LABELS->value )
							->setName( $t("Labels") )
							->setDescription( $t("Vraag naar de labels van de cursus") )
							->setDefaultValue( $this->askLabels )
							->addSetCallback( function ( $value ) {
								$this->askLabels = $value ?? $this->askLabels;
							}),
						( new BoolInput() )
							->setIndex( SearchOptionsEnum::ASK_CODE_95->value )
							->setName( $t("Code 95") )
							->setDescription( $t("Vraag naar de code 95 van de cursus") )
							->setDefaultValue( $this->askCode95 )
							->addSetCallback( function ( $value ) {
								$this->askCode95 = $value ?? $this->askCode95;
							}),
						( new BoolInput() )
							->setIndex( SearchOptionsEnum::ASK_SOOB->value )
							->setName( $t("SOOB") )
							->setDescription( $t("Vraag naar de SOOB van de cursus") )
							->setDefaultValue( $this->askSoob )
							->addSetCallback( function ( $value ) {
								$this->askSoob = $value ?? $this->askSoob;
							}),
						( new BoolInput() )
							->setIndex( SearchOptionsEnum::ASK_E_LEARNING->value )
							->setName( $t("E-learning") )
							->setDescription( $t("Vraag naar de e-learning van de cursus") )
							->setDefaultValue( $this->askELearning )
							->addSetCallback( function ( $value ) {
								$this->askELearning = $value ?? $this->askELearning;
							}),
						( new BoolInput() )
							->setIndex( SearchOptionsEnum::ASK_STAP->value )
							->setName( $t("Stap") )
							->setDescription( $t("Vraag naar de stap van de cursus") )
							->setDefaultValue( $this->askStap )
							->addSetCallback( function ( $value ) {
								$this->askStap = $value ?? $this->askStap;
							})
					),
				( new RadioInput(new IntType()) )
					->setIndex( SearchOptionsEnum::OUTPUT_FORMAT->value )
					->setName( $t("Output-formaat") )
					->setDescription( $t("Welk output-formaat moet worden gebruikt?") )
					->setDefaultValue( $this->outputFormat )
					->setOptions([
						[
							"value" => 0,
							"label" => "Block"
						],
						[
							"value" => 1,
							"label" => "Block2"
						],
						[
							"value" => 2,
							"label" => "Table"
						],
						[
							"value" => 3,
							"label" => "List"
						],
					])
					->addSetCallback( function ( $value ) {
						$this->outputFormat = $value ?? $this->outputFormat;
					})
			);
	}

	/**
	 * @return array{values:mixed[], subGroups:array[], subGroupAliases:string[]}
	 */
	public function getEnumMapping(): array {
		return [
			"values"          => [
				SearchOptionsEnum::ASK_TITLE->value => &$this->askTitle,
				SearchOptionsEnum::ASK_LOCATION->value => &$this->askLocation,
				SearchOptionsEnum::ASK_LABELS->value => &$this->askLabels,
				SearchOptionsEnum::ASK_CODE_95->value => &$this->askCode95,
				SearchOptionsEnum::ASK_SOOB->value => &$this->askSoob,
				SearchOptionsEnum::ASK_E_LEARNING->value => &$this->askELearning,
				SearchOptionsEnum::ASK_STAP->value => &$this->askStap,
				SearchOptionsEnum::OUTPUT_FORMAT->value => &$this->outputFormat,
			],
			"subGroups"       => [],
			"subGroupAliases" => []
		];
	}

	public function isAskTitle(): bool {
		$this->logUse( SearchOptionsEnum::ASK_TITLE );
		return $this->askTitle;
	}

	public function isAskLocation(): bool {
		$this->logUse( SearchOptionsEnum::ASK_LOCATION );
		return $this->askLocation;
	}

	public function isAskLabels(): bool {
		$this->logUse( SearchOptionsEnum::ASK_LABELS );
		return $this->askLabels;
	}

	public function isAskCode95(): bool {
		$this->logUse( SearchOptionsEnum::ASK_CODE_95 );
		return $this->askCode95;
	}

	public function isAskSoob(): bool {
		$this->logUse( SearchOptionsEnum::ASK_SOOB );
		return $this->askSoob;
	}

	public function isAskELearning(): bool {
		$this->logUse( SearchOptionsEnum::ASK_E_LEARNING );
		return $this->askELearning;
	}

	public function isAskStap(): bool {
		$this->logUse( SearchOptionsEnum::ASK_STAP );
		return $this->askStap;
	}

	public function getOutputFormat(): string {
		$this->logUse( SearchOptionsEnum::OUTPUT_FORMAT );
		return match ($this->outputFormat) {
			1 => "Block2",
			2 => "Table",
			3 => "List",
			default => "Block",
		};
	}
}