<?php

namespace CouponsPlus\App\Coupon\Tree\Finders;

use CouponsPlus\App\Conditions\ItemsSet;
use CouponsPlus\App\Coupon\CartComponentsSet;
use CouponsPlus\App\Coupon\Tree\Abilities\FindableOffersFromBranch;
use CouponsPlus\App\Coupon\Tree\Abilities\FindableOffersFromNode;
use CouponsPlus\App\Coupon\Tree\Abilities\NodeData;
use CouponsPlus\App\Coupon\Tree\Abilities\NodeDataFilterableSet;
use CouponsPlus\Original\Collections\Collection;
use CouponsPlus\App\Coupon\Tree\Testable\PathRecorderFilterableSet;

class RuntimeNodeOffersFinder implements FindableOffersFromNode
{
    private FindableOffersFromBranch $findableOffersFromBranch;
    private NodeDataFilterableSet $setFiltererFromNodeData;

    public function __construct(
        NodeDataFilterableSet $setFiltererFromNodeData,
        /* This is a decorator too.
         * Depending on the type of branch, FindableOffersFromBranch will pick a finder for: 
         *  -leaves Branch (offers)
         *  -Numeric Filter Tiered branch & Free combination of conditions and filters Tiered Branch (tiered)
         *  
         *  -maybe a leaf & node branch combo?
         */
        FindableOffersFromBranch $findableOffersFromBranch
    )
    {
        $this->findableOffersFromBranch = $findableOffersFromBranch;
        $this->setFiltererFromNodeData = $setFiltererFromNodeData;
    } 

    public function findOffers(ItemsSet $itemsSet, NodeData $node): CartComponentsSet
    {
        /**
         * Path is recorder here by the PathRecorderFilterableSet (decorator)
         */
        (object) $filteredSet = $this->setFiltererFromNodeData->filterSet(
            $itemsSet,
            $node,
            new NodeDatasCollection(new Collection([$node]))
        );

        // her ewe prolly should add a nested object that early returns when the set is empty
        return $this->findableOffersFromBranch->findOffers(
            $filteredSet,
            $node->getBranch()
        );
    } 
}