<?php

namespace Planaday\Entities\Booking\Validators;

use Planaday\Config\Booking\Form\Company\CompanySettings;
use Planaday\Entities\Booking\DTO\Address;
use Planaday\Entities\Booking\DTO\BookingCompany;
use Planaday\Entities\Booking\DTO\BookingInvoice;
use Planaday\Entities\Booking\PostRequest\BookingCompanyFieldEnum;
use Planaday\Platform\PlatformAbstraction\LocalizationController;
use Planaday\Utility\DataFilters\AdvancedValidatorFactory;
use Planaday\Utility\DataFilters\InvalidException;
use Planaday\Utility\DataFilters\TypeValidator;

class BookingCompanyValidator {
	public function __construct(
		protected LocalizationController $localisationService,
		protected CompanySettings $companySettings,
		protected TypeValidator $typeValidator,
		protected AdvancedValidatorFactory $advancedValidatorFactory,
		protected BookingAddressValidator $addressValidator,
		protected BookingInvoiceValidator $invoiceValidator
	) {}

	public function getFromPost(array $postData): BookingCompany|array {
		$t      = $this->localisationService;
		$type   = $this->typeValidator;
		$errors = [];

		try {
			$name = $type->str($postData[BookingCompanyFieldEnum::NAME] ?? null);
			if (empty($name)){
				$errors[BookingCompanyFieldEnum::NAME] = $t->translate('Bedrijfsnaam is verplicht bij de bedrijfsinformatie');
			}
		} catch (InvalidException ) {
			$errors[BookingCompanyFieldEnum::NAME] = $t->translate("De bedrijfsnaam is niet geldig bij de bedrijfsinformatie");
		}

		try {
			$email = $type->str($postData[BookingCompanyFieldEnum::EMAIL] ?? null);
			if (empty($email)){
				$errors[BookingCompanyFieldEnum::EMAIL] = $t->translate('Email is verplicht bij de bedrijfsinformatie');
			} elseif ( $this->advancedValidatorFactory->isEmail($email) === false) {
				$errors[BookingCompanyFieldEnum::EMAIL] = $t->translate('Bedrijfsemail is geen geldig email adres');
			}
		} catch (InvalidException ) {
			$errors[BookingCompanyFieldEnum::EMAIL] = $t->translate("De e-mail is niet geldig bij de bedrijfsinformatie");
		}

		try {
			$phoneNumber = $type->str($postData[BookingCompanyFieldEnum::PHONE_NUMBER] ?? null);
			if ( $this->companySettings->isAskPhoneNumber() && $this->companySettings->isPhoneNumberRequired() && empty($phoneNumber)) {
				$errors[BookingCompanyFieldEnum::PHONE_NUMBER] = $t->translate('Telefoonnummer is verplicht bij de bedrijfsinformatie');
			}
		} catch (InvalidException ) {
			$errors[BookingCompanyFieldEnum::PHONE_NUMBER] = $t->translate("Het telefoonnummer is niet geldig bij de bedrijfsinformatie");
		}

		try {
			$addressArray = $type->array($postData[BookingCompanyFieldEnum::ADDRESS] ?? null);
			if ( !empty($addressArray) ){
				$address = $this->addressValidator->getFromPost( $addressArray, 'Bedrijfs' );
				if ( !$address instanceof Address ) {
					$errors[BookingCompanyFieldEnum::ADDRESS] = $address;
				}
			} else {
				$errors[BookingCompanyFieldEnum::ADDRESS] = $t->translate('Adres is verplicht bij de bedrijfsinformatie');
			}
		} catch (InvalidException ) {
			$errors[BookingCompanyFieldEnum::ADDRESS] = $t->translate("De adres informatie is niet geldig bij de bedrijfsinformatie");
		}

		try {
			$invoiceArray = $type->array($postData[BookingCompanyFieldEnum::INVOICE] ?? null);
			if (!empty($invoiceArray)){
				$invoice = $this->invoiceValidator->getFromPost( $invoiceArray );
				if ( !$invoice instanceof BookingInvoice ) {
					$errors[BookingCompanyFieldEnum::INVOICE] = $invoice;
				}
			} elseif ( $this->companySettings->getInvoiceSettings()->isAskForEmail() && $this->companySettings->getInvoiceSettings()->isEmailRequired()) {
				$errors[BookingCompanyFieldEnum::INVOICE] = $t->translate('factuur informatie is verplicht bij de bedrijfsinformatie');
			}
		} catch (InvalidException ) {
			$errors[BookingCompanyFieldEnum::INVOICE] = $t->translate("De financiële informatie is niet geldig bij de bedrijfsinformatie");
		}

		if ( count( $errors ) > 0 || !isset($name, $address, $email)) {
			return $errors;
		}

		return (new BookingCompany())
			->setName($name)
			->setAddress($address)
			->setEmail($email)
			->setPhoneNumber($phoneNumber ?? null)
			->setInvoice($invoice ?? null);
	}
}