<?php
/**
 * Save quote at customer end.
 *
 * @category  Magetop Extensions
 * @package   Magetop_Quotesystem
 * @author    Magetop Developer
 * @copyright Copyright (c) Magetop (https://www.magetop.com)
 * @license   https://www.magetop.com/license.html
 */

namespace Magetop\Quotesystem\Block\Adminhtml\Productgrid;

use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\LayoutFactory;
use Magento\Catalog\Model\ProductFactory;
use Magento\Framework\App\ObjectManager;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Variations\Prices;

class Productoptions
{

    /**
     * @var \Magento\Catalog\Model\Product
     */
    protected $_catalogProduct;

    /**
     * @var [type]
     */
    protected $_allowProducts;

    /**
     * @var \Magento\Framework\Json\Helper\Data
     */
    protected $_jsonHelper;

    /**
     * @var \Magento\Framework\View\Result\LayoutFactory
     */
    protected $resultLayoutFactory;

    /**
     * @param LayoutFactory                                             $resultLayoutFactory
     * @param Context                                                   $context
     * @param ProductFactory                                            $catalogProduct
     * @param \Magento\Framework\Json\Helper\Data                       $jsonHelper
     * @param \Magento\Framework\Controller\Result\JsonFactory          $resultJsonFactory
     * @param Prices                                                    $variationPrices
     */
    public function __construct(
        LayoutFactory $resultLayoutFactory,
        Context $context,
        ProductFactory $catalogProduct,
        \Magento\Framework\Json\Helper\Data $jsonHelper,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
        Prices $variationPrices = null
    ) {
        $this->resultLayoutFactory = $resultLayoutFactory;
        $this->_catalogProduct = $catalogProduct;
        $this->_jsonHelper = $jsonHelper;
        $this->resultJsonFactory = $resultJsonFactory;
        $this->variationPrices = $variationPrices ?: ObjectManager::getInstance()->get(
            Prices::class
        );
    }

    /**
     * Get config data in json
     */
    public function getJsonConfig()
    {
        $store = $this->getCurrentStore();
        $currentProduct = $this->getProduct();
        $this->helper = $this->_objectManager->get(\Magento\ConfigurableProduct\Helper\Data::class);
        $options = $this->helper->getOptions($currentProduct, $this->getAllowProducts());
        $this->configurableAttributeData = $this->_objectManager->get(
            \Magento\ConfigurableProduct\Model\ConfigurableAttributeData::class
        );
        $attrData = $this->configurableAttributeData->getAttributesData($currentProduct, $options);
        $this->localeFormat = $this->_objectManager->get(\Magento\Framework\Locale\Format::class);
        $configData = [
            'attributes' => $attrData['attributes'],
            'template' => str_replace('%s', '<%- data.price %>', $store->getCurrentCurrency()->getOutputFormat()),
            'currencyFormat' => $store->getCurrentCurrency()->getOutputFormat(),
            'optionPrices' => $this->getOptionPrices(),
            'priceFormat' => $this->localeFormat->getPriceFormat(),
            'prices' => $this->variationPrices->getFormattedPrices($this->getProduct()->getPriceInfo()),
            'productId' => $currentProduct->getId(),
            'chooseText' => __('Choose an Option...'),
            'images' => $this->getOptionImages(),
            'index' => isset($options['index']) ? $options['index'] : [],
        ];

        if ($currentProduct->hasPreconfiguredValues() && !empty($attrData['defaultValues'])) {
            $configData['defaultValues'] = $attrData['defaultValues'];
        }

        $configData = array_merge($configData, $this->_getAdditionalConfigData());

        return $configData;
    }

    /**
     * Get current store
     */
    public function getCurrentStore()
    {
        $this->_storeManager = $this->_objectManager->get(\Magento\Store\Model\StoreManagerInterface::class);
        return $this->_storeManager->getStore();
    }

    /**
     * Get Product
     */
    public function getProduct()
    {
        $this->product = $this->_objectManager->get(\Magento\Catalog\Model\Product::class);
        $params = $this->getRequest()->getParams();
        $productId = $params['id'];
        
        $product = $this->product->load($productId);
        
        if ($product && $product->getTypeInstance()->getStoreFilter($product) === null) {
            $product->getTypeInstance()->setStoreFilter($this->_storeManager->getStore(), $product);
        }
        return $product;
    }

    /**
     * Get allow Product
     */
    public function getAllowProducts()
    {
        if (!$this->_allowProducts) {
            $products = [];
            $this->catalogProduct = $this->_objectManager->get(\Magento\Catalog\Helper\Product::class);
            $skipSaleableCheck = $this->catalogProduct->getSkipSaleableCheck();
            $allProducts = $this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct(), null);
            foreach ($allProducts as $product) {
                if ($product->isSaleable() || $skipSaleableCheck) {
                    $products[] = $product;
                }
            }
            $this->_allowProducts = $products;
        }
        return $this->_allowProducts;
    }

     /**
      * Collect price options
      *
      * @return array
      */
    protected function getOptionPrices()
    {
        $prices = [];
        foreach ($this->getAllowProducts() as $product) {
            $tierPrices = [];
            $priceInfo = $product->getPriceInfo();
            $tierPriceModel =  $priceInfo->getPrice('tier_price');
            $tierPricesListData = $tierPriceModel->getTierPriceList();
            $this->localeFormat = $this->_objectManager->get(\Magento\Framework\Locale\Format::class);
            foreach ($tierPricesListData as $tierPriceData) {
                $tierPrices[] = [
                    'qty' => $this->localeFormat->getNumber($tierPriceData['price_qty']),
                    'price' => $this->localeFormat->getNumber($tierPriceData['price']->getValue()),
                    'percentage' => $this->localeFormat->getNumber(
                        $tierPriceModel->getSavePercent($tierPriceData['price'])
                    ),
                ];
            }

            $prices[$product->getId()] =
                [
                    'oldPrice' => [
                        'amount' => $this->localeFormat->getNumber(
                            $priceInfo->getPrice('regular_price')->getAmount()->getValue()
                        ),
                    ],
                    'basePrice' => [
                        'amount' => $this->localeFormat->getNumber(
                            $priceInfo->getPrice('final_price')->getAmount()->getBaseAmount()
                        ),
                    ],
                    'finalPrice' => [
                        'amount' => $this->localeFormat->getNumber(
                            $priceInfo->getPrice('final_price')->getAmount()->getValue()
                        ),
                    ],
                    'tierPrices' => $tierPrices,
                    'msrpPrice' => [
                        'amount' => $this->localeFormat->getNumber(
                            $product->getMsrp()
                        ),
                    ],
                 ];
        }
        return $prices;
    }

    /**
     * Get product images for configurable variations
     *
     * @return array
     * @since 100.1.10
     */
    protected function getOptionImages()
    {
        $imagesData = [];
        foreach ($this->getAllowProducts() as $prodData) {
            $productImages = $this->helper->getGalleryImages($prodData) ?: [];
            foreach ($productImages as $imageDt) {
                $imagesData[$prodData->getId()][] =
                    [
                        'thumb' => $imageDt->getData('small_image_url'),
                        'img' => $imageDt->getData('medium_image_url'),
                        'full' => $imageDt->getData('large_image_url'),
                        'caption' => $imageDt->getLabel(),
                        'position' => $imageDt->getPosition(),
                        'isMain' => $imageDt->getFile() == $prodData->getImage(),
                        'type' => str_replace('external-', '', $imageDt->getMediaType()),
                        'videoUrl' => $imageDt->getVideoUrl(),
                    ];
            }
        }

        return $imagesData;
    }

    /**
     * Returns additional values for js config, con be overridden by descendants
     *
     * @return array
     */
    protected function _getAdditionalConfigData()
    {
        return [];
    }
}
