<?php

namespace CouponsPlus\App\Coupon\Tree\OfferItemsSetFilters;

use CouponsPlus\App\Conditions\ItemsSet;
use CouponsPlus\App\Coupon\Tree\Abilities\CardData;
use CouponsPlus\App\Coupon\Tree\Finders\Sets\OfferItems;
use CouponsPlus\App\Coupon\Tree\Cart\CartModifiedException;
use CouponsPlus\App\Coupon\Tree\Abilities\OffersItemsSetResolvable;
use CouponsPlus\App\Coupon\Tree\Factories\ConditionFilterOrOfferFromDataFactory;

class OffersItemsSetResolverFromData implements OffersItemsSetResolvable
{
    protected ConditionFilterOrOfferFromDataFactory $offersFactory;
    protected CardData $offerData;

    public function __construct(ConditionFilterOrOfferFromDataFactory $offersFactory)
    {
        $this->offersFactory = $offersFactory;
    }

    public function setOfferData(CardData $offerData): void
    {
        $this->offerData = $offerData;
    }

    /**
     * @throws CartModifiedException
     */
    public function resolveItemsToUse(ItemsSet $filteredItems): OfferItems
    {
        // ok so here lets create and instance of the offer to request the items to use from the give itemsset
        (object) $runtimeOffer = $this->offersFactory->create('offer', $this->offerData);

        if ($runtimeOffer instanceof OffersItemsSetResolvable) {
            /**
             * Dispatch to the offer the responsibility to pick the items to use from the passed items set
             * MAY THROW AND CART MODIFIED EXCEPTION AND SO EXECUTION WILL END FOR THIS INSTANCE (A NEW ONE WILL BE CREATED)
             */
            (object) $offerItems = $runtimeOffer->resolveItemsToUse($filteredItems);
        } else {
            // it's just a standard offer that applies discounts to all passed items
            /**
             * Always set the itemsSet instead of adding its items
             *in order to preserve its state
             */
            (object) $offerItems = new OfferItems($filteredItems);
        }

        return $offerItems;
    }
}