<?php

namespace Planaday\Utility\Debug;

class ObjectToArrayConverter {
	/**
	 * @param object $object
	 *
	 * @return array<mixed>
	 */
	public function convert(object $object): array {
		$array = var_export($object, true );
		preg_match("@.+array\(@", $array, $matches);
		$array = substr($array, strlen($matches[0] ?? ''));
		$parsingString = $array;
		return $this->getArrayFromString($parsingString) ?? [];
	}

	/**
	 * @param string $string
	 *
	 * @return array<mixed>|null
	 */
	private function getArrayFromString(string &$string): ?array{
		$builtArray = [];

		while (true){
			preg_match("@(\\))|(('(([^']|(\\\\'))*)'|([0-9]+)) => (('(([^']|\\\\')*)')|(([^,'(]*)(\\((array\\()?)?)))@", $string, $matches, PREG_UNMATCHED_AS_NULL);

			$pos = strpos($string, $matches[0] ?? '');
			if ($pos !== false && isset($matches[0])) {
				$string = substr_replace($string, '', $pos, strlen($matches[0]));
			}

			if (($matches[1] ?? null) !== null){
				if (count($builtArray) == 0) return null;
				return $builtArray;
			}

			if (($matches[2] ?? null) == null){
				return $builtArray;
			}

			$match4or7 = $matches[4] ?? $matches[7] ?? null;

			if (isset($matches[9], $matches[10]) && $match4or7 !== null) {
				$builtArray[$match4or7] = $matches[10];
			}

			if (($matches[12] ?? null) !== null && $match4or7 !== null){
				if (str_contains($matches[12], 'array(') || str_contains($matches[12], 'array (')){
					$key = $match4or7;

					$isObject = str_contains($matches[12], '__set_state(');
					if ($isObject && isset($matches[13])) $key .= ' (' . substr(str_replace('\\', "\\ ",trim($matches[13])), 0, -13) . ')';

					$builtArray[$key] = $this->getArrayFromString($string) ?? 'NULL';

					if ($isObject){
						$pos = strpos($string, ')');
						if ($pos !== false) {
							$string = substr_replace($string, '', $pos, 1);
						}
					}
				} else {
					$builtArray[$match4or7] = $matches[12];
				}
			}

			preg_match("@[^')]*@", $string, $match);
			$string = substr($string, strlen($match[0] ?? ''));
		}
	}
}