<?php
namespace Newland\Toubiz\Map\Neos\Utility;

/*
 * This file is part of the "toubiz-map-neos" package.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 */

use Neos\Flow\Annotations as Flow;

/**
 * Category mapping utility.
 *
 * @Flow\Scope("singleton")
 */
class CategoryMappingUtility
{
    /**
     * Finds all original id's from the yaml category mapping configuration
     * based on configured selection.
     *
     * @param array $haystack The collection to search for (usually the full yaml configuration).
     * @param array $needles  The items needed from the collection.
     * @param array $ids     Existing array with original id's.
     * @return array          Result array with original id's.
     */
    public static function getMappedIdsFromConfiguration(array $haystack, array $needles, array &$ids = [])
    {
        foreach ($haystack as $category) {
            if (in_array($category['value'], $needles) && array_key_exists('map', $category)) {
                $ids = array_merge($ids, $category['map']);
            }

            if (array_key_exists('children', $category)) {
                self::getMappedIdsFromConfiguration($category['children'], $needles, $ids);
            }
        }
        return $ids;
    }

    /**
     * Finds all parent and child categories matching the given needles, removing
     * non-matching children.
     *
     * @param array $haystack The collection to search for (usually the full yaml configuration).
     * @param array $needles  The items needed from the collection.
     * @param array $tree    Existing category tree.
     * @param array $parent   The parent category for the current iteration.
     * @return array          Resulting category tree.
     */
    public static function getCategoriesFromConfiguration(
        array $haystack,
        array $needles,
        array &$tree = [],
        $parent = null
    ) {
        foreach ($haystack as $category) {
            if (array_key_exists('children', $category)) {
                self::getCategoriesFromConfiguration(
                    $category['children'],
                    $needles,
                    $tree,
                    ($parent ? $parent : $category)
                );
            } else {
                if (in_array($category['value'], $needles) && array_key_exists('map', $category)) {
                    $item = ($parent ? $parent : $category);

                    // Remove non-matching children.
                    $item['children'] = array_filter(
                        $item['children'],
                        function ($value) use ($needles) {
                            return in_array($value['value'], $needles);
                        }
                    );

                    $tree[] = $item;
                }
            }
        }

        return $tree;
    }
}
