<?php

namespace CouponsPlus\App\Coupon\Tree\ItemSetsToDiscount;

use WC_Product;
use CouponsPlus\App\Conditions\ItemsSet;
use CouponsPlus\App\Conditions\PendingCartItem;
use CouponsPlus\App\Conditions\VirtualCartItem;
use CouponsPlus\Original\Collections\Collection;
use CouponsPlus\App\Coupon\Tree\Finders\Sets\OfferItems;

/**
 * This converts all ItemsToDiscountCollection into a collection of OfferItems
 */
class ItemsToDiscountToOfferItemsAdapter
{

    protected ItemsSet $filteredItems;

    public function __construct(ItemsSet $filteredItems)
    {
        $this->filteredItems = $filteredItems;
    }

    public function adapt(ItemsSetToDiscountCollection $itemsSetToDiscountCollection): OfferItems
    {
        [$itemsToDiscount, $suggestedItems] = $this->convertItemsToDiscount(
            $itemsSetToDiscountCollection
        );

        return new OfferItems(
            $itemsToDiscount,
            $this->filteredItems,
            // here give me the items that cannot be added to the cart AS A COLLECTION OF ItemToDiscount[]
            // these will be the items that cannot be added to the cart but are eligible in some way to be discounted
            $suggestedItems
        );
    }

    private function convertItemsToDiscount(ItemsSetToDiscountCollection $itemsSetToDiscountCollection): array
    {
        /**
         * These may be items that should be added to the cart later in the process.
         * Not necessarily all of these exist in the cart, some may have been queued for addition (pending)
         */
        (object) $convertedItemSet = new ItemsSet([]);
        (object) $suggestedProducts = new Collection([]);

        /** @var ItemsSetToDiscount $itemsSetToDiscount */
        foreach ($itemsSetToDiscountCollection->getAll()->asArray() as $itemsSetToDiscount) {
            // only the items that:
            // -were found
            // -weren't found but can be added to the cart
            if ($itemsSetToDiscount->canFillTheRequiredQuantity()) {
                $convertedItemSet->addItems($itemsSetToDiscount->getItemSetWithExactQuantityRequired());
            } elseif ($itemsSetToDiscount->areMissing() && $itemsSetToDiscount->productToDiscount->canBeAutomaticallyAddedToTheCart()) {
                // ok so the item may be added to the cart automatically so lets create a pending state
                // ONLY ONE ITEM IS SUPPORTED CURRENTLY!
                $productId = $itemsSetToDiscount->productToDiscount->getSubject();
                $product = wc_get_product($productId);
                $isVariation = $product->is_type('variation');

                $convertedItemSet->addItems(new ItemsSet([
                     PendingCartItem::create(
                         new VirtualCartItem([
                             'key' => $productId,
                             'quantity' => $itemsSetToDiscount->getMissingQuantity(),
                             'product_id' => $isVariation ? $product->get_parent_id() : $productId,
                             'variation_id' => $isVariation ? $productId : 0,
                             'variation' => $isVariation ? $product->get_variation_attributes() : [],
                             // you might think that loading the product here is expensive, but since we are going to
                             // add it to the cart, the product WILL be loaded anyway.
                             'data' => $product
                         ]),
                         $itemsSetToDiscount->getMissingQuantity()
                     )
                 ]));
            } else {
                // cannot be added to the cart automatically, so skip add it to the suggested bag
                $suggestedProducts->push($itemsSetToDiscount->productToDiscount);
            }
        }

        return [$convertedItemSet, $suggestedProducts];
    }
}