<?php

namespace Planaday\Config;

use Planaday\Utility\Debug\Log\Logging;
use Planaday\Utility\DependencyInjection\Attributes\Scoped;
use Planaday\Utility\DependencyInjection\Container;
use Planaday\Utility\DependencyInjection\InjectionImpossibleException;
use Planaday\Utility\DependencyInjection\Scope;

#[Scoped]
class ConfigFetcher {
	use Logging;

	public function __construct(
		protected Container $registry,
		protected Scope $scope
	) {}

	/**
	 * @param OptionGroupEnum[] $enums
	 *
	 * @return EnumMappedSettings[]
	 */
	public function getHighestMappedSettings(array $enums, ?array &$filter): array {
		$upperSettingClasses = [];
		$relationArray = [];
		/** @var OptionGroupEnum[] $enums */
		$enums = array_unique($enums, SORT_REGULAR);

		foreach ($enums as $enum) {
			$currentEnum = $enum;
			$currentClass = get_class($enum);
			if (!isset($relationArray[$currentClass])) {
				$relationArray[$currentClass] = [];
			}
			$relationArray[$currentClass][] = $enum->value;

			while ($currentEnum->getParentEnum() !== null) {
				$nextEnum = $currentEnum->getParentEnum();
				$nextClass = get_class($nextEnum);
				if (!isset($relationArray[$nextClass])) {
					$relationArray[$nextClass] = [$currentClass => &$relationArray[$currentClass]];
				} elseif (!isset($relationArray[$nextClass][$currentClass])) {
					$relationArray[$nextClass][$currentClass] = &$relationArray[$currentClass];
				}
				$currentEnum = $nextEnum;
				$currentClass = $nextClass;
			}

			if (!isset($upperSettingClasses[get_class($currentEnum)]))
				$upperSettingClasses[get_class($currentEnum)] = $currentClass::getClassName();
		}

		/** @var EnumMappedSettings[] $upperSettings */
		$upperSettings = [];
		$filter = [];
		foreach ($upperSettingClasses as $enumClass => $settingClass) {
			$filter[$enumClass] = $relationArray[$enumClass];
			try {
				$upperSettings[] = $this->registry->getInstance($settingClass, $this->scope);
			} catch (InjectionImpossibleException $e) {
				$this->logError("Could not get upper settings: " . $e->getMessage());
			}
		}

		return $upperSettings;
	}
}