<?php

namespace Planaday\Config\OptionGroups\Course\Detail;

use Planaday\Platform\PlatformAbstraction\LocalizationController;
use Planaday\Utility\DataFilters\InvalidFieldsException;
use Planaday\Utility\DataFilters\TypeValidator;
use Planaday\Utility\Debug\Log\Logging;

class DetailOptionsValidator {
	use Logging;

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

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

	public function __construct( TypeValidator $typeValidator, LocalizationController $translator) {
		$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 ) {
				$this->logError('Invalid field: ' . $field . ' with error: ' . $fieldException->getMessage());
				$errors[ $field ] = $tr->translate(
					'Het ' . strtolower($field) . ' veld bij de detail opties is met ongeldige data ingevuld.'
				);
			}

			$output = $errors;
			return false;
		}

		if (!($data[DetailOptionsEnum::SHOW_DAY_PART_LIST] ?? false)){
			if ($data[DetailOptionsEnum::SHOW_E_LEARNING_DAY_PART] ?? false){
				$errors[DetailOptionsEnum::SHOW_DAY_PART_LIST] = [false];
				$errors[DetailOptionsEnum::SHOW_E_LEARNING_DAY_PART] = $tr->translate(
					'Als u een e-learning label bij de dagdelen wilt laten zien moet de lijst met dagdelen worden getoond'
				);
			}

			if ($data[DetailOptionsEnum::SHOW_LOCATION_DAY_PART] ?? false){
				$errors[DetailOptionsEnum::SHOW_DAY_PART_LIST] = [false];
				$errors[DetailOptionsEnum::SHOW_LOCATION_DAY_PART] = $tr->translate(
					'Als u de locatie van een dagdeel wilt laten zien moet de lijst met dagdelen worden getoond'
				);
			}

			if ($data[DetailOptionsEnum::SHOW_DESCRIPTION_DAY_PART] ?? false){
				$errors[DetailOptionsEnum::SHOW_DAY_PART_LIST] = [false];
				$errors[DetailOptionsEnum::SHOW_DESCRIPTION_DAY_PART] = $tr->translate(
					'Als u de omschrijving van een dagdeel wilt laten zien moet de lijst met dagdelen worden getoond'
				);
			}

			if ($data[DetailOptionsEnum::INCLUDE_E_LEARNING_DAY_PARTS] ?? false){
				$errors[DetailOptionsEnum::SHOW_DAY_PART_LIST] = [false];
				$errors[DetailOptionsEnum::INCLUDE_E_LEARNING_DAY_PARTS] = $tr->translate(
					'Als u de e-learning dagdelen wilt laten zien moet de lijst met dagdelen worden getoond'
				);
			}
		}

		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;

		$int = [
			DetailOptionsEnum::SELECTED_DETAIL_PAGE,
			DetailOptionsEnum::OVERRIDDEN_DETAIL_PAGE,
			DetailOptionsEnum::COURSE_NOT_FOUND_PAGE,
		];

		$boolean = [
			DetailOptionsEnum::SHOW_SOOB_LABEL,
			DetailOptionsEnum::SHOW_CODE_95_LABEL,
			DetailOptionsEnum::SHOW_LABELS,
			DetailOptionsEnum::SHOW_DAY_PART_COUNT,
			DetailOptionsEnum::SHOW_DAY_PART_LIST,
			DetailOptionsEnum::SHOW_LOCATION_DAY_PART,
			DetailOptionsEnum::SHOW_E_LEARNING_DAY_PART,
			DetailOptionsEnum::SHOW_LEVEL_COURSE,
			DetailOptionsEnum::SHOW_DESCRIPTION_DAY_PART,
			DetailOptionsEnum::SHOW_AVAILABILITY,
			DetailOptionsEnum::SHOW_START_GUARANTEE_LABEL,
			DetailOptionsEnum::SHOW_MONEY_BACK_LABEL,
			DetailOptionsEnum::SHOW_FINANCIAL_INFO,
			DetailOptionsEnum::SHOW_PRICE,
			DetailOptionsEnum::SHOW_PRICE_WITH_AND_WITHOUT_TAX,
			DetailOptionsEnum::SHOW_ICONS,
			DetailOptionsEnum::INCLUDE_E_LEARNING_DAY_PARTS,
			DetailOptionsEnum::SHOW_E_LEARNING_ICON,
			DetailOptionsEnum::SHOW_DESCRIPTION,
			DetailOptionsEnum::SHOW_LABELS_DAY_PART
		];

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

}