<?php

namespace Planaday\Config\OptionGroups\Booking\Submission;

use Planaday\Config\OptionGroups\Booking\Submission\Mail\MailOptionsValidator;
use Planaday\Config\OptionGroups\Booking\Submission\Redirecting\RedirectOptionsValidator;
use Planaday\Platform\PlatformAbstraction\LocalizationController;
use Planaday\Utility\DataFilters\InvalidFieldsException;
use Planaday\Utility\DataFilters\TypeValidator;
use Planaday\Utility\Debug\Log\Logging;

class BookingSubmissionOptionsValidator {
	use Logging;

	/** @var MailOptionsValidator */
	private $mailOptionsValidator;

	/** @var RedirectOptionsValidator */
	private $redirectOptionsValidator;

	/** @var TypeValidator */
	private $typeValidator;

	/** @var LocalizationController */
	private $translator;

	public function __construct(
		TypeValidator $typeValidator,
		LocalizationController $translator,
		MailOptionsValidator $mailOptionsValidator,
		RedirectOptionsValidator $redirectOptionsValidator
	) {
		$this->mailOptionsValidator       = $mailOptionsValidator;
		$this->redirectOptionsValidator   = $redirectOptionsValidator;
		$this->typeValidator            = $typeValidator;
		$this->translator               = $translator;
	}

	/**
	 * @param array $data
	 * @param array|null $output if valid, clean data is returned here. if not, errors will be returned here
	 *
	 * @return bool true if valid, false if not
	 */
	public function validate( array $data, ?array &$output): bool {
		$errors = [];
		$tr = $this->translator;

		try {
			$data = $this->getSafeData( $data );
		} catch ( InvalidFieldsException $e ) {
			foreach ( $e->getInvalidFields() as $field => $fieldException ) {
				$errors[ $field ] = $tr->translate(
					'Het ' . strtolower($field) . ' veld bij de boeking submission opties is met ongeldige data ingevuld.'
				);
			}

			$output = $errors;
			return false;
		}

		if (!$this->mailOptionsValidator->validate($data[BookingSubmissionOptionsEnum::MAIL] ?? [], $mailOutput)) {
			$errors[BookingSubmissionOptionsEnum::MAIL . '-isValid'] = $tr->translate("De mail opties zijn niet geldig.");
			$errors[BookingSubmissionOptionsEnum::MAIL] = $mailOutput;
		} else {
			$data[BookingSubmissionOptionsEnum::MAIL] = $mailOutput;
		}

		if (!$this->redirectOptionsValidator->validate($data[BookingSubmissionOptionsEnum::REDIRECT] ?? [], $redirectOutput)) {
			$errors[BookingSubmissionOptionsEnum::REDIRECT . '-isValid'] = $tr->translate("De redirect opties zijn niet geldig.");
			$errors[BookingSubmissionOptionsEnum::REDIRECT] = $redirectOutput;
		} else {
			$data[BookingSubmissionOptionsEnum::REDIRECT] = $redirectOutput;
		}

		if ( count( $errors ) > 0 ) {
			$output = $errors;
			$this->logWarning("data is not valid", $errors);
			return false;
		}

		$output = $data;
		return true;
	}

	/**
	 * @param array $data
	 *
	 * @return array
	 * @throws InvalidFieldsException
	 */
	private function getSafeData(array $data): array {
		$tv = $this->typeValidator;

		$arrays = [
			BookingSubmissionOptionsEnum::REDIRECT,
			BookingSubmissionOptionsEnum::MAIL
		];

		return $tv->getSafeData($data, [], $arrays);
	}

}