<?php

namespace Planaday\Config\Booking\Form\Company;

use Planaday\Config\BasicEnumMappedSetting;
use Planaday\Config\BasicSettingsLog;
use Planaday\Config\Booking\Form\Company\Invoice\InvoiceOptionsEnum;
use Planaday\Config\Booking\Form\Company\Invoice\InvoiceSettings;
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\DataGrouping\Collection;
use Planaday\Utility\DependencyInjection\Attributes\Scoped;
use Planaday\Utility\FormBuilder\Conditions\InputValueCondition;
use Planaday\Utility\FormBuilder\InputFields\BoolInput;
use Planaday\Utility\FormBuilder\Structures\BasicGroup;
use Planaday\Utility\FormBuilder\Structures\CollapsibleGroup;

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

	protected bool $allowCompanies = true;
	protected bool $asCompanyDefault = false;
	protected bool $askPhoneNumber = false;
	protected bool $phoneNumberRequired = false;

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

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

		return ( new BasicGroup() )
			->setIndex( CompanyOptionsEnum::class )
			->addContents(
				$allowCompanies = (new BoolInput())
					->setIndex( CompanyOptionsEnum::ALLOW_COMPANIES->value )
					->setName( $t( "Bedrijven toestaan?" ) )
					->setDescription( $t( "Moeten bedrijven worden toegestaan?" ) )
					->setDefaultValue( $this->allowCompanies )
					->addSetCallback( function ( $value ) {
						$this->allowCompanies = $value ?? $this->allowCompanies;
					}),
				(new BasicGroup())
					->addConditions(
						(new InputValueCondition($allowCompanies))->equals()->value(true)
					)->addContents(
						(new BoolInput())
							->setIndex( CompanyOptionsEnum::AS_COMPANY_DEFAULT->value )
							->setName( $t( "Bedrijven als standaard instellen?" ) )
							->setDescription( $t( "Moeten bedrijven als standaard worden ingesteld?" ) )
							->setDefaultValue( $this->asCompanyDefault )
							->addSetCallback( function ( $value ) {
								$this->asCompanyDefault = $value ?? $this->asCompanyDefault;
							}),
						(new CollapsibleGroup())
							->setHeader($t("Financieel"))
							->setDescription($t("De opties voor het vragen van financiële informatie in de boeking."))
							->addContents(
								$this->invoiceSettings->getFormGroup()
							),
						$askPhoneNumber = (new BoolInput())
							->setIndex( CompanyOptionsEnum::ASK_PHONE_NUMBER->value )
							->setName( $t( "Telefoonnummer vragen?" ) )
							->setDescription( $t( "Moet er een telefoonnummer bij het bedrijf gevraagd worden?" ) )
							->setDefaultValue( $this->askPhoneNumber )
							->addSetCallback( function ( $value ) {
								$this->askPhoneNumber = $value ?? $this->askPhoneNumber;
							}),
						(new BasicGroup())
							->addConditions(
								(new InputValueCondition($askPhoneNumber))->equals()->value(true)
							)->addContents(
								(new BoolInput())
									->setIndex( CompanyOptionsEnum::PHONE_NUMBER_REQUIRED->value )
									->setName( $t( "Telefoonnummer verplicht?" ) )
									->setDescription( $t( "Moet dit telefoonnummer verplicht zijn?" ) )
									->setDefaultValue( $this->phoneNumberRequired )
									->addSetCallback( function ( $value ) {
										$this->phoneNumberRequired = $value ?? $this->phoneNumberRequired;
									})
							)->addClasses("pad-subgroup")
					)
			);
	}

	/**
	 * @return array{values:mixed[], subGroups:array[], subGroupAliases:string[]}
	 */
	public function getEnumMapping(): array {
		return [
			"values"          => [
				CompanyOptionsEnum::ALLOW_COMPANIES->value => &$this->allowCompanies,
				CompanyOptionsEnum::AS_COMPANY_DEFAULT->value => &$this->asCompanyDefault,
				CompanyOptionsEnum::ASK_PHONE_NUMBER->value => &$this->askPhoneNumber,
				CompanyOptionsEnum::PHONE_NUMBER_REQUIRED->value => &$this->phoneNumberRequired,
			],
			"subGroups"       => [
				CompanyOptionsEnum::INVOICE->value => $this->invoiceSettings->getEnumMapping(),
			],
			"subGroupAliases" => [
				InvoiceOptionsEnum::class => CompanyOptionsEnum::INVOICE->value,
			]
		];
	}

	public function isAllowCompanies(): bool {
		$this->logUse( CompanyOptionsEnum::ALLOW_COMPANIES );
		return $this->allowCompanies;
	}

	public function isAsCompanyDefault(): bool {
		$this->logUse( CompanyOptionsEnum::AS_COMPANY_DEFAULT );
		return $this->asCompanyDefault;
	}

	public function isAskPhoneNumber(): bool {
		$this->logUse( CompanyOptionsEnum::ASK_PHONE_NUMBER );
		return $this->askPhoneNumber;
	}

	public function isPhoneNumberRequired(): bool {
		$this->logUse( CompanyOptionsEnum::PHONE_NUMBER_REQUIRED );
		return $this->phoneNumberRequired;
	}

	public function getInvoiceSettings(): InvoiceSettings {
		return $this->invoiceSettings;
	}

	public function getUsageLog(): Collection {
		return new Collection(...( $this->usageLog ?? [] ), ...$this->invoiceSettings->getUsageLog());
	}
}