<?php
/**
 * Mageplaza
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Mageplaza.com license that is
 * available through the world-wide-web at this URL:
 * https://www.mageplaza.com/LICENSE.txt
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade this extension to newer
 * version in the future.
 *
 * @category    Mageplaza
 * @package     Mageplaza_QuickCart
 * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)
 * @license     https://www.mageplaza.com/LICENSE.txt
 */

namespace Mageplaza\QuickCart\Plugin\Controller\Cart;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare;
use Magento\Catalog\Block\Product\ProductList\Item\Container;
use Magento\Catalog\ViewModel\Product\Listing\PreparePostData;
use Magento\Checkout\Controller\Cart\Add as MagentoAdd;
use Magento\Cms\Block\Block;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\View\LayoutInterface;
use Magento\Framework\View\Result\PageFactory;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Wishlist\Block\Catalog\Product\ProductList\Item\AddTo\Wishlist;
use Mageplaza\QuickCart\Block\AjaxCart\Popup as AjaxCartPopup;
use Mageplaza\QuickCart\Helper\QuickViewData as HelperData;
use Mageplaza\QuickCart\Model\Config\Source\BlockType;
use Magento\Checkout\Model\Session;

/**
 * Class Add
 * @package Mageplaza\QuickCart\Plugin\Controller\Cart
 */
class Add
{
    /**
     * @var PageFactory
     */
    protected $pageFactory;

    /**
     * @var ManagerInterface
     */
    protected $messageManager;

    /**
     * @var StoreManagerInterface
     */
    protected $_storeManager;

    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

    /**
     * @var HelperData
     */
    protected $_helperData;

    /**
     * @var AjaxCartPopup
     */
    protected $_popup;

    /**
     * @var Session
     */
    protected $quoteSession;

    /**
     * Add constructor.
     *
     * @param HelperData $helperData
     * @param StoreManagerInterface $storeManager
     * @param ManagerInterface $messageManager
     * @param PageFactory $pageFactory
     * @param AjaxCartPopup $popup
     * @param ProductRepositoryInterface $productRepository
     * @param Session $quoteSession
     */
    public function __construct(
        HelperData $helperData,
        StoreManagerInterface $storeManager,
        ManagerInterface $messageManager,
        PageFactory $pageFactory,
        AjaxCartPopup $popup,
        ProductRepositoryInterface $productRepository,
        Session $quoteSession
    ) {
        $this->_helperData       = $helperData;
        $this->_storeManager     = $storeManager;
        $this->messageManager    = $messageManager;
        $this->pageFactory       = $pageFactory;
        $this->_popup            = $popup;
        $this->productRepository = $productRepository;
        $this->quoteSession      = $quoteSession;
    }

    /**
     * @param MagentoAdd $subject
     * @param $result
     *
     * @return mixed
     * @throws NoSuchEntityException
     * @throws LocalizedException
     */
    public function afterExecute(MagentoAdd $subject, $result)
    {
        if ($this->_helperData->isEnabled()) {
            $isAjaxCart       = $subject->getRequest()->getParam('mpajaxcart');
            $isAjaxCartPopup  = $subject->getRequest()->getParam('mppopup');
            $isQuickViewPopup = $subject->getRequest()->getParam('mpquickview');
            $productId        = (int) $subject->getRequest()->getParam('product');
            $product          = $this->_initProductById($productId);
            $layout           = $this->pageFactory->create()->getLayout();
            $backUrl          = $subject->getResponse()->getContent();
            $quote = $this->quoteSession->getQuote();
            if($this->_helperData->checkHyvaTheme() && !$isAjaxCart) {
                return $result;
            }
            $result           = [];
            if ($quote->getId() && $this->_helperData->isShowMiniCart() && $quote->getItemsCount() === 1) {
                $result['show_mini_cart'] = true;
            }

            if ($this->_helperData->isAddToCart() && $isAjaxCart) {
                $messageList = [];
                if ($itemMessage = $this->messageManager->getMessages()->getItems()) {
                    foreach ($itemMessage as $message) {
                        $messageList[] = $message->getText();
                    }

                    if (!empty(array_filter($messageList))) {
                        $result['error']   = true;
                        $result['message'] = $messageList;
                    }
                }
                $this->messageManager->getMessages()->clear();
                $result['backUrl'] = HelperData::jsonDecode($backUrl);

                //fix error not showing block when adding to cart from another ajax cart.
                $result['success']    = true;
                if($this->_helperData->checkHyvaTheme()) {
                    $successBlock         = $layout->createBLock(AjaxCartPopup::class)
                        ->setTemplate('Mageplaza_QuickCart::hyva/ajaxcart/success.phtml')
                        ->setProductItem($product);
                } else {
                    $successBlock         = $layout->createBLock(AjaxCartPopup::class)
                        ->setTemplate('Mageplaza_QuickCart::ajaxcart/success.phtml')
                        ->setProductItem($product);
                }
                $result['html_popup'] = $this->addSalesBlock($successBlock, $layout)->toHtml();


                return $subject->getResponse()->representJson(HelperData::jsonEncode($result));
            }

            if ($isAjaxCartPopup) {  // process add to cart on ajax cart popup
                if ($backUrl === '[]') {
                    $result['success'] = true;
                    $successBlock      = $layout->createBLock(AjaxCartPopup::class)
                        ->setTemplate('Mageplaza_QuickCart::ajaxcart/success.phtml')
                        ->setProductItem($product);
                    $result['html']    = $this->addSalesBlock($successBlock, $layout)->toHtml();
                } else {
                    $messageList     = [];
                    $result['error'] = true;
                    if ($this->messageManager->getMessages()->getItems()) {
                        foreach ($this->messageManager->getMessages()->getItems() as $message) {
                            $messageList[] = $message->getText();
                        }

                        $result['message'] = $messageList;
                    }
                }

                return $subject->getResponse()->representJson(HelperData::jsonEncode($result));
            }

            /**
             * Process if don't apply ajax add to cart on quickview popup
             */
            if ($isQuickViewPopup) {
                $messageList     = [];
                $result['error'] = HelperData::jsonDecode($backUrl);
                if ($this->messageManager->getMessages()->getItems()) {
                    foreach ($this->messageManager->getMessages()->getItems() as $message) {
                        $messageList[] = $message->getText();
                    }

                    $result['message'] = $messageList;
                }

                return $subject->getResponse()->representJson(HelperData::jsonEncode($result));
            }
        }

        return $result;
    }

    /**
     * @param $productId
     *
     * @return bool|ProductInterface
     * @throws NoSuchEntityException
     */
    private function _initProductById($productId)
    {
        if ($productId) {
            $storeId = $this->_storeManager->getStore()->getId();
            try {
                return $this->productRepository->getById($productId, false, $storeId);
            } catch (NoSuchEntityException $e) {
                return false;
            }
        }

        return false;
    }

    /**
     * @param AjaxCartPopup $successBlock
     * @param LayoutInterface $layout
     *
     * @return mixed
     */
    private function addSalesBlock($successBlock, $layout)
    {
        if ($blockType = $this->_helperData->getBlockType()) {
            if ($blockType === BlockType::CMS_STATIC_BLOCK) {
                $cmsBlock = $layout->createBlock(Block::class)->setBlockId($this->_helperData->getCmsBlockId());
                $successBlock->setChild(BlockType::CMS_STATIC_BLOCK, $cmsBlock);
            } else {
                $compareBlock = $layout->createBlock(
                    Container::class,
                    'related.product.addto'
                )->setChild(
                    'wishlist',
                    $layout->createBlock(
                        Wishlist::class,
                        'related.product.addto.wishlist'
                    )->setTemplate('Magento_Wishlist::catalog/product/list/addto/wishlist.phtml')
                )->setChild(
                    'compare',
                    $layout->createBlock(
                        Compare::class,
                        'related.product.addto.compare'
                    )->setTemplate('Magento_Catalog::product/list/addto/compare.phtml')
                );

                $successBlock->setViewModel($this->_helperData->createObject(PreparePostData::class))
                    ->setChild(
                        'addto',
                        $compareBlock
                    );
            }

            $successBlock->setType($blockType);
        }

        return $successBlock;
    }
}
