<?php
/**
 * Webkul Software.
 * 
 * PHP version 7.0+
 *
 * @category  Webkul
 * @package   Webkul_MobikulGraphQL
 * @author    Webkul <support@webkul.com>
 * @copyright 2010-2019 Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html ASL Licence
 * @link      https://store.webkul.com/license.html
 */

declare(strict_types=1);
namespace Webkul\MobikulGraphQL\Model\Resolver;

class WishlistData implements \Magento\Framework\GraphQl\Query\ResolverInterface
{

    protected $helper;
    protected $customerId;
    protected $storeManager;
    protected $pricingHelper;
    protected $helperCatalog;
    protected $productFactory;
    protected $wishlistProvider;
    protected $productConfigurationHelper;

    public function __construct(
        \Webkul\MobikulGraphQL\Helper\Data $helper,
        \Webkul\MobikulCore\Helper\Catalog $helperCatalog,
        \Magento\Wishlist\Model\Wishlist $wishlistProvider,
        \Magento\Framework\Pricing\Helper\Data $pricingHelper,
        \Magento\Catalog\Model\ProductFactory $productFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Catalog\Helper\Product\Configuration $productConfigurationHelper
    ) {
        $this->helper = $helper;
        $this->storeManager = $storeManager;
        $this->pricingHelper = $pricingHelper;
        $this->helperCatalog = $helperCatalog;
        $this->productFactory = $productFactory;
        $this->wishlistProvider = $wishlistProvider;
        $this->productConfigurationHelper = $productConfigurationHelper;
    }

    /**
     * @inheritdoc
     */
    public function resolve(
        \Magento\Framework\GraphQl\Config\Element\Field $field,
        $context,
        \Magento\Framework\GraphQl\Schema\Type\ResolveInfo $info,
        array $value = null,
        array $args = null
    ) {
        $returnArray = [];
        $token = $args["token"] ?? "";
        $pageNumber = $args["pageNumber"] ?? 1;
        $this->customerId = $this->helper->getCustomerByToken($token)->getId();
        $this->storeId = $this->storeManager->getStore()->getId();
        $wishlist = $this->wishlistProvider->loadByCustomerId($this->customerId, true);
        $wishListCollection = $wishlist->getItemCollection();
        // Applying pagination //////////////////////////////////////////////////
        if ($pageNumber >= 1) {
            $returnArray["totalCount"] = $wishListCollection->getSize();
            $pageSize = $this->helperCatalog->getPageSize();
            $wishListCollection->setPageSize($pageSize)->setCurPage($pageNumber);
        }
        // Getting wishlist data /////////////////////////////////////////////////
        $wishList = $this->getWishListData($wishListCollection);
        $returnArray["wishList"] = $wishList;
        return $returnArray;
    }

    /**
     * GetWishListData Function to get wishlist data
     *
     * @param \Magento\Wishlist\Model\Wishlist $wishListCollection wishListCollection
     *
     * @return array* 
     */
    protected function getWishListData($wishListCollection)
    {
        $wishList = [];
        foreach ($wishListCollection as $item) {
            $product = $this->productFactory->create()->load($item->getProductId());
            $eachWishData = [];
            $eachWishData["id"] = $item->getId();
            $eachWishData["sku"] = $product->getSku();
            $eachWishData["qty"] = $item->getQty() * 1;
            $eachWishData["name"] = $product->getName();
            $eachWishData["price"] = $this->helperCatalog->stripTags($this->pricingHelper->currency($product->getFinalPrice()));
            $eachWishData["productId"] = $product->getId();
            $eachWishData["thumbNail"] = $this->helperCatalog->getImageUrl($product, 1000);
            $eachWishData["description"] = $item->getDescription();
            $options = $this->productConfigurationHelper->getOptions($item);
            $eachWishData["options"] = [];
            if (count($options) > 0) {
                foreach ($options as $option) {
                    $eachOption = [];
                    $eachOption["label"] = html_entity_decode($option["label"]);
                    if (is_array($option["value"])) {
                        $eachOption["value"] = $option["value"];
                    } else {
                        $eachOption["value"][] = $this->helperCatalog->stripTags($option["value"]);
                    }
                    $eachWishData["options"][] = $eachOption;
                }
            }
            $eachWishData["options"] = json_encode($eachWishData["options"]);
            $productData = $this->helperCatalog->getOneProductRelevantData($product, $this->storeId, 1000, $this->customerId);
            $customOption = [];
            foreach ($item->getOptions() as $option) {
                $customOption[$option->getCode()] = $option->getValue();
            }
            if ($productData["typeId"] == "bundle") {
                $price = 0.0;
                $selections = $item->getProduct()->getTypeInstance(true)->getOrderOptions($item->getProduct());
                if (!empty($selections["bundle_options"])) {
                    foreach ($selections["bundle_options"] as $selection) {
                        if (!empty($selection["value"])) {
                            $price += array_sum(array_column($selection["value"], 'price'));
                        }
                    }
                }
                $productData["finalPrice"] =  $price;
                $productData["formattedFinalPrice"] = $this->helperCatalog->stripTags($this->pricingHelper->currency($price));
            }
            if ($productData["typeId"] == "grouped") {
                $productData["finalPrice"] =  $this->calculatePrice($item->getProduct(), $customOption);
                $productData["formattedFinalPrice"] = $this->helperCatalog->stripTags($this->pricingHelper->currency($this->calculatePrice($item->getProduct(), $customOption)));
            }
            $wishList[] = array_merge($eachWishData, $productData);
        }
        return $wishList;
    }

    protected function calculatePrice($product, $customOption)
    {
        $value = 0.0;
        $typeInstance = $product->getTypeInstance();
        $associatedProducts = $typeInstance
            ->setStoreFilter($product->getStore(), $product)
            ->getAssociatedProducts($product);
        foreach ($associatedProducts as $product) {
            $optionValue = $customOption["associated_product_" . $product->getId()] ?? null;
            if (!$optionValue) {
                continue;
            }
            $finalPrice = $product->getPriceInfo()
                ->getPrice(FinalPrice::PRICE_CODE)
                ->getValue();
            $value += $finalPrice * $optionValue;
        }
        return $value;
    }

}