<?php

namespace CouponsPlus\App\Coupon\Tree\ItemSetsToDiscount;

use WC_Cart;
use Exception;
use CouponsPlus\App\Coupon\Tree\Cart\CartModifier;
use CouponsPlus\App\Coupon\Tree\Cart\CartModifiedException;
use CouponsPlus\App\Coupon\Tree\Abilities\ItemSetToDiscountHandler;
use CouponsPlus\App\Coupon\Tree\Abilities\OptionalItemSetToDiscountHandler;

class CartAdderItemSetToDiscountHandler implements ItemSetToDiscountHandler, OptionalItemSetToDiscountHandler
{
    protected CartModifier $cartModifier;

    public function __construct(CartModifier $cartModifier)
    {
        $this->cartModifier = $cartModifier;
    }

    /**
     * Only on items that can be added to the cart
     */
    public function canHandle(ItemsSetToDiscount $itemsSetToDiscount): bool
    {
        return $itemsSetToDiscount->productToDiscount->canBeAutomaticallyAddedToTheCart();
    }

    /**
     * @throws Exception|CartModifiedException
     */
    public function handle(ItemsSetToDiscount $itemSetToDiscount)
    {
        /**
         * The whole SpecificCartProductsResolverStrategy instance is going to come to a halt after adding to the cart.
         *
         * This is going to happen to every product we add until we can no longer add new products.
         *
         * Why? because wc_cart::add_to_cart() will trigger a recalculation of the cart, which will run the engine again.
         * then cart modifier will throw an exception here because we don't need to run this code because it has been run already from the triggered recalculations.
         */
        $this->cartModifier->modify(function (WC_Cart $cart) use ($itemSetToDiscount) {
            $cart->add_to_cart(
                $itemSetToDiscount->productToDiscount->getSubject(),
                $itemSetToDiscount->getMissingQuantity()
            );
        });
    }
}