<?php

namespace Planaday\Entities\Booking\Form\Company;

use Planaday\Entities\Booking\DTO\Address;
use Planaday\Entities\Booking\DTO\BookingCompany;
use Planaday\Entities\Booking\DTO\BookingInvoice;
use Planaday\Entities\Booking\DTO\ContactPerson;
use Planaday\Entities\Booking\Form\Address\AddressFormFactory;
use Planaday\Entities\Booking\Form\Company\ContactPerson\ContactPersonFormFactory;
use Planaday\Entities\Booking\Form\Company\ContactPerson\ContactPersonSettings;
use Planaday\Entities\Booking\Form\Company\Invoice\InvoiceFormFactory;
use Planaday\Platform\PlatformAbstraction\LocalizationController;
use Planaday\Utility\DependencyInjection\Attributes\Scoped;
use Planaday\Utility\FormBuilder\Conditions\InputValueCondition;
use Planaday\Utility\FormBuilder\DataTypes\BoolType;
use Planaday\Utility\FormBuilder\InputFields\RadioInput;
use Planaday\Utility\FormBuilder\InputFields\StringInput;
use Planaday\Utility\FormBuilder\LayoutItems\Header;
use Planaday\Utility\FormBuilder\Structures\BasicGroup;
use Planaday\Utility\FormBuilder\Validators\RegexValidator;
use Planaday\Utility\FormBuilder\Validators\Required;
use Planaday\Utility\RegexUtility;

#[Scoped]
class CompanyFormFactory {

	public function __construct(
		protected AddressFormFactory $addressFormFactory,
		protected InvoiceFormFactory $invoiceFormFactory,
		protected ContactPersonFormFactory $contactPersonFormFactory,
		protected LocalizationController $localizationController,
		protected CompanySettings $settings,
		protected ContactPersonSettings $contactPersonSettings,
	) {}

	public function getFormForObject(BookingCompany $bookingCompany): BasicGroup{
		$t = function (string $text) {
			return $this->localizationController->translate($text);
		};

		$outputGroup = (new BasicGroup());
		$address = $bookingCompany->getAddress() ?? new Address();
		$bookingCompany->setAddress($address);

		$contactPerson = $bookingCompany->getContactPerson() ?? new ContactPerson();
		$invoice = $bookingCompany->getInvoice() ?? new BookingInvoice();
		$bookingCompany->setInvoice($invoice);

		$outputGroup->addContents(
			( new StringInput() )
				->setIndex(CompanyFieldsEnum::Name->value)
				->setName($t("Naam") . " *")
				->setDescription($t("De naam van het bedrijf"))
				->setPlaceholder($t("Naam"))
				->setAutocomplete("work organization")
				->addSetCallback(function ($value) use ($bookingCompany) {
					$bookingCompany->setName($value ?? '');
				})->addValidator(
					new Required($t("Bedrijfsnaam is verplicht"))
				),
			( new StringInput() )
				->setIndex(CompanyFieldsEnum::Email->value)
				->setName($t("Email") . " *")
				->setDescription($t("De email van het bedrijf"))
				->setPlaceholder($t("Email"))
				->setAutocomplete("work email")
				->addSetCallback(function ($value) use ($bookingCompany) {
					$bookingCompany->setEmail($value ?? '');
				})->addValidator(
					new Required($t("Email is verplicht")),
					new RegexValidator("Email", RegexUtility::SIMPLE_EMAIL_REGEX, $t("Het e-mailadres is niet geldig"))
				),
			( new BasicGroup() )
				->setIndex(CompanyFieldsEnum::Address->value)
				->addContents(
					( new Header($t("Adres"), 5) ),
					$this->addressFormFactory->getFormForObject($address, true, "work"),
				),
		);

		if ($this->settings->isAskPhoneNumber()) {
			$isRequired = $this->settings->isPhoneNumberRequired();
			$outputGroup->addContents(
				$phoneNumber = ( new StringInput() )
					->setIndex(CompanyFieldsEnum::PhoneNumber->value)
					->setName($t("Telefoonnummer") . ($isRequired ? " *" : ""))
					->setDescription($t("Het telefoonnummer van het bedrijf"))
					->setPlaceholder($t("Telefoonnummer"))
					->setAutocomplete("work tel")
					->addSetCallback(function ($value) use ($bookingCompany) {
						$bookingCompany->setPhoneNumber($value ?? '');
					})
			);

			if ( $isRequired ) {
				$phoneNumber->addValidator(
					new Required($t("Telefoonnummer is verplicht"))
				);
			}
		}

		$outputGroup->addContents(
			( new BasicGroup() )
				->setIndex(CompanyFieldsEnum::Invoice->value)
				->addContents(
					$this->invoiceFormFactory->getFormForObject($invoice)
				)
		);

		if ($this->contactPersonSettings->isAskContactPerson()) {
			$outputGroup->addContents(
				( new BasicGroup() )
					->setIndex(CompanyFieldsEnum::ContactPerson->value)
					->addContents(
						( new Header($t("Contactpersoon"), 5) ),
						$contactPersonToggle = ( new RadioInput( new BoolType() ) )
							->setIndex("toggle")
							->setName($t("Contactpersoon toevoegen?"))
							->setDescription($t("Alle communicatie die naar de cursisten wordt verzonden, wordt ook verstuurd naar deze contactpersoon."))
							->setOptions([
								["value" => true, "label" => $t("Ja")],
								["value" => false, "label" => $t("Nee")],
							])
							->setDefaultValue(false)
							->addSetCallback(function ($value) use ($bookingCompany, $contactPerson) {
								$bookingCompany->setContactPerson($value ? $contactPerson : null);
							}),
						( new BasicGroup() )
							->addContents(
								$this->contactPersonFormFactory->getFormForObject($contactPerson),
							)->addConditions(
								( new InputValueCondition( $contactPersonToggle ) )->equals()->value( true )
							),
					)
			);
		}

		return $outputGroup;
	}
}