<?php

namespace CouponsPlus\App\Coupon\Tree;

use CouponsPlus\App\Conditions\ItemsSet;
use CouponsPlus\Original\Collections\Collection;
use CouponsPlus\App\Coupon\Tree\Abilities\FilterableGroup;

class DifferenceTestableGroup implements FilterableGroup
{
    public function filter(Collection $testables, ItemsSet $passedItems): ItemsSet
    {
        // so lets filter all the passed items through each testable and collect each set and then call the main passed item without() with each of the sets
        (object) $ignorableItemsSets = $testables->map(function ($testable) use ($passedItems) : ItemsSet {
            return $testable->filterSet($passedItems);
        });

        // here union all the ignorable sets into one single set to prevent sum'ing overlapping items multiple times
        // so product b x 1 and product b x 2 should yield the set with product b x 2 (highest qty) instead of product b x 3 (sum of qty's)
        // and product c x 1 and product c x 1 should yield product c x 1, not product c x 2
        /** @var ItemsSet $ignorableItemsSet */
        foreach ($ignorableItemsSets->asArray() as $ignorableItemsSet) {
            (object) $itemsToExclude = $ignorableItemsSet->getItems();

            if (!isset($unionedItemsToExclude)) {
                $unionedItemsToExclude = $ignorableItemsSet;
            } else {
                $unionedItemsToExclude = $unionedItemsToExclude->unionByMaxQuantity($ignorableItemsSet);
            }
        }

        return $passedItems->without($unionedItemsToExclude ?? new ItemsSet([]));
    }
}