<?php

namespace Planaday\Utility\DataGrouping;

use ArrayAccess;
use Countable;
use Traversable;

class ArrayWalker {
	public function &walk(string $path, ArrayAccess|array &$data, bool $forceWalk = false, bool $returnLastValue = true): mixed{
		preg_match("@([^\[\]]+)(\[|]\[)@", $path, $baseName);

		if (isset($baseName[1], $baseName[0]) && $data){
			preg_match_all("@\[([^]]+)]@", substr_replace($path, "", 0 , strlen($baseName[0]) - 1), $matches, PREG_PATTERN_ORDER);

			$deepestLayer =& $data[$baseName[1]];
			foreach ($matches[1] as $arrayLayer){
				if (!ArrayFunctions::is_arrayType($deepestLayer)) {
					if (!$forceWalk) {
						if($returnLastValue) break;
						$nullValue = null;
						return $nullValue;
					}
					$deepestLayer = [];
				}

				$deepestLayer =& $deepestLayer[$arrayLayer];
			}

			return $deepestLayer;
		}

		return $data[$path];
	}

	/**
	 * @param array<mixed> $data
	 * @param string $keyPrefix
	 * @param int $maxDepth
	 *
	 * @return array<mixed>
	 */
	public function getAsFlatArray(iterable $data, string $keyPrefix = '', int $maxDepth = -1): array{
		$outputArray = [];

		foreach ($data as $key => $value ){
			if (ArrayFunctions::is_arrayType($value)){
			    if($maxDepth == 0) continue;
				$flatArrayOfValue = $this->getAsFlatArray($value, $keyPrefix . '[' . $key . ']', $maxDepth - 1);
				foreach ($flatArrayOfValue as $subKey => $subValue){
					$outputArray[$subKey] = $subValue;
				}
			} else {
				$outputArray[$keyPrefix . '[' . $key . ']'] = $value;
			}
		}

		return $outputArray;
	}
}