<?php
/**
 * Webkul Software.
 *
 * @category Webkul
 *
 * @author    Webkul
 * @copyright Copyright (c) Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html
 */

namespace Webkul\AdvanceSeoManager\Model\RichSnippet\Context;

class Product extends AbstractContext
{

    /**
     * @var \Webkul\AdvanceSeoManager\Helper\Data
     */
    protected $_helper;
    public function __construct(
        \Magento\Catalog\Model\ProductFactory $productFactory,
        \Webkul\AdvanceSeoManager\Helper\JsonLd $jsonLdHelper,
        \Magento\Framework\Json\Helper\Data $jsonHelper,
        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
        \Magento\Catalog\Helper\ImageFactory $imageHelperFactory,
        \Webkul\AdvanceSeoManager\Model\RichSnippet\Context\Product\DataPoolInterface $productDataPool,
        \Webkul\AdvanceSeoManager\Helper\Data $helper
    ) {
        $this->productFactory = $productFactory;
        $this->jsonLdHelper = $jsonLdHelper;
        $this->jsonHelper = $jsonHelper;
        $this->_categoryFactory = $categoryFactory;
        $this->imageHelperFactory = $imageHelperFactory;
        $this->productDataPool = $productDataPool;
        $this->_helper = $helper;
    }

    /**
     * inherit
     */
    public function build($contextData)
    {
        $jsonLdData = $this->createJsonLdFormatArray($contextData);
        if (count($jsonLdData) > 0) {
            return $this->getJsonLdFormat($this->jsonHelper->jsonEncode($jsonLdData));
        }
        return '';
    }

    /**
     * inherit
     */
    public function createJsonLdFormatArray($contextData)
    {
        $richSnippetFormat = $this->jsonLdHelper->getProductRichSnippetData();
        $data = [];
        if ($contextData && $contextData->getId()) {
            $data = $this->getRichProductSnippet($contextData, $richSnippetFormat);
            return $data;
        }
        return [];
    }

    /**
     * get rich snippet format data
     *
     * @param  Magento\Catalog\Model\Product $contextData
     * @param  array                         $richSnippetFormat
     * @return array
     */
    public function getRichProductSnippet($contextData, $richSnippetFormat)
    {
        $data = [];
        $data = $this->productDataPool->get('product')->getData($contextData);
        if ($richSnippetFormat && count($richSnippetFormat) > 0) {
            foreach ($richSnippetFormat as $fields => $status) {
                if ($status) {
                    $data = $this->switchCase($data, $fields, $contextData, $richSnippetFormat);
                }
            }
        }

        return $data;
    }

    public function switchCase($data, $fields, $contextData, $richSnippetFormat)
    {
        switch ($fields) {
            case 'brand':
                if ($contextData->getData($richSnippetFormat['brand_attribute_code'])) {
                    $data['brand'] = $this->getBrand($richSnippetFormat['brand_attribute_code'], $contextData);
                }
                break;
            case 'weight':
                if ($contextData->getTypeId() == 'simple') {
                    if ($contextData->getWeight()) {
                        $data['weight'] = $contextData->getWeight();
                    }
                }
                break;
            case 'category':
                $data['category'] = $this->getProductCategory($contextData);
                break;
            case 'image':
                $data['image'] = $this->getProductImage($contextData);
                break;
            case 'logo':
                $data['logo'] = $this->getProductLogo($contextData);
                break;
            case 'review':
                $data['review'] = $this->getProductReview($contextData);
                break;
            case 'aggregateRating':
                $data['aggregateRating'] = $this->getProductAggregateRating($contextData);
                break;
            case 'offers':
                $data['offers'] = $this->getProductOffers($contextData);
                break;
            case 'sku':
                $data['sku'] = $this->getProductSku($contextData);
                break;
            case 'url':
                $data['url'] = $this->getProductUrl($contextData);
                break;
            default:
        }
        return $data;
    }

    /**
     * get attribute code
     *
     * @param string $attributeCode
     * @param Magento\Catalog\Model\Product $product
     * @return string
     */
    public function getBrand($attributeCode, $product)
    {
        $attr = $product->getResource()->getAttribute($attributeCode);
        if ($attr->usesSource()) {
            $optionText = $attr->getSource()->getOptionText($product->getData($attributeCode));
            if (is_array($optionText)) {
                return implode(',', $optionText);
            }

            return $optionText;
            
        }

        return $product->getData($attributeCode);
    }

    /**
     * get current product category data
     *
     * @param  Magento\Catalog\Model\Product $product
     * @return string|array
     */
    public function getProductCategory($product)
    {
        return $this->productDataPool->get('category')->getData($product);
    }

    /**
     * get current product image
     *
     * @param  Magento\Catalog\Model\Product $product
     * @return string|array
     */
    public function getProductImage($product)
    {
        return $this->imageHelperFactory->create()->init($product, 'product_page_image_small')->getUrl();
    }

    /**
     * get current product logo
     *
     * @param  Magento\Catalog\Model\Product $product
     * @return string|array
     */
    public function getProductLogo($product)
    {
        return $this->_helper->getStoreLogo();
    }

    /**
     * get current product review
     *
     * @param  Magento\Catalog\Model\Product $product
     * @return string|array
     */
    public function getProductReview($product)
    {
        return $this->productDataPool->get('review')->getData($product);
    }

    /**
     * get current product aggregate rating
     *
     * @param  Magento\Catalog\Model\Product $product
     * @return string|array
     */
    public function getProductAggregateRating($product)
    {
        return $this->productDataPool->get('aggregateRating')->getData($product);
    }

    /**
     * get current product offers
     *
     * @param  Magento\Catalog\Model\Product $product
     * @return string|array
     */
    public function getProductOffers($product)
    {
        return $this->productDataPool->get('offers')->getData($product);
    }

    /**
     * get current product sku
     *
     * @param  Magento\Catalog\Model\Product $product
     * @return string|array
     */
    public function getProductSku($product)
    {
        return $product->getSku();
    }

    /**
     * get current product url
     *
     * @param  Magento\Catalog\Model\Product $product
     * @return string|array
     */
    public function getProductUrl($product)
    {
        return $product->getProductUrl();
    }
}
