<?php
namespace Autogedal\Extend\Block;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Model\Product\Gallery\ImagesConfigFactoryInterface;
use Magento\Catalog\Model\Product\Image\UrlBuilder;
use Autogedal\Extend\Model\CategoryHierarchy;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Catalog\Helper\Output;
use Magento\Framework\Phrase;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\App\Config\ScopeConfigInterface;

class RickSnippet extends \Smartwave\Porto\Block\RickSnippet
{
    const CATEGORY_SPECS_PATH = 'leadlion/rich_snippet_specs/config';

    protected $attributeHelper;
    protected $storeManager;
    protected $catHeirarchy;
    protected $voteCollection;
    protected $serializer;
    protected $resource;
    protected $scopeConfig;

    /**
     * Review resource model
     *
     * @var \Magento\Review\Model\ResourceModel\Review\CollectionFactory
     */
    protected $_reviewsColFactory;

    /**
     * @var array
     */
    private $galleryImagesConfig;

     /**
     * @var ImagesConfigFactoryInterface
     */
    private $galleryImagesConfigFactory;

    /**
     * @var UrlBuilder
     */
    private $imageUrlBuilder;

    public function __construct(
        \Magento\Catalog\Block\Product\Context $productContext,
        \Magento\Review\Model\Review\SummaryFactory $reviewSummaryFactory,
        \Magento\Framework\View\Element\Template\Context $context,
        StoreManagerInterface $storeManager,
        ImagesConfigFactoryInterface $galleryImagesConfigFactory,
        UrlBuilder $urlBuilder,
        CategoryHierarchy $catHeirarchy,
        \Magento\Review\Model\ResourceModel\Review\CollectionFactory $collectionFactory,
        \Magento\Review\Model\ResourceModel\Rating\Option\Vote\CollectionFactory $voteCollection,
        SerializerInterface $serializer,
        Output $attributeHelper,
        ResourceConnection $resource,
        ScopeConfigInterface $scopeConfig,
        array $galleryImagesConfig = [],
        array $data = []
    ) {
        parent::__construct($productContext, $reviewSummaryFactory, $context, $data);
        $this->attributeHelper = $attributeHelper;
        $this->serializer = $serializer;
        $this->_reviewsColFactory = $collectionFactory;
        $this->urlBuilder = $urlBuilder;
        $this->galleryImagesConfigFactory = $galleryImagesConfigFactory;
        $this->storeManager = $storeManager;
        $this->galleryImagesConfig = $galleryImagesConfig;
        $this->imageUrlBuilder = $urlBuilder;
        $this->catHeirarchy = $catHeirarchy;
        $this->voteCollection = $voteCollection;
        $this->resource = $resource;
        $this->scopeConfig = $scopeConfig;
    }

    public function getReviewRating($reviewId)
    {
        $rating = $this->voteCollection->create();
        $rating->addRatingInfo()->addOptionInfo()->addRatingOptions()->addFieldToFilter('review_id', $reviewId);
        return !empty($rating->getData()) ? $rating->getData()[0]['value'] : 1;
    }

    /**
     * Get collection of reviews
     *
     * @return ReviewCollection
     */
    public function getReviewsCollection(\Magento\Catalog\Model\Product $product)
    {
        return $this->_reviewsColFactory->create()->addStoreFilter(
                $product->getStoreId()
            )->addStatusFilter(
                \Magento\Review\Model\Review::STATUS_APPROVED
            )->addEntityFilter(
                'product',
                $this->getProduct()->getId()
            )->setDateOrder();
    }

    public function getMaterial(\Magento\Catalog\Model\Product $product)
    {
        if ($product->getAttributeText('material')) {
            return $product->getAttributeText('material');
        } elseif ($product->getAutoMaterialBare()) {
            return $product->getAutoMaterialBare();
        } elseif ($product->getCutiecarligMaterial()) {
            return $product->getCutiecarligMaterial();
        } elseif ($product->getAttributeText('material_cutii_portbagaj')) {
            return $product->getAttributeText('material_cutii_portbagaj');
        } elseif ($product->getAttributeText('scut_material')) {
            return $product->getAttributeText('scut_material');
        } elseif ($product->getSupbicMaterial()) {
            return $product->getSupbicMaterial();
        }

        return null;
    }

    public function getCuloare(\Magento\Catalog\Model\Product $product)
    {
        if ($product->getAttributeText('culoare')) {
            return $product->getAttributeText('culoare');
        } elseif ($product->getAttributeText('culoare_cutii_portbagaj')) {
            return $product->getAttributeText('culoare_cutii_portbagaj');
        }
        return null;
    }

    public function getCategoryHierarchyByProduct(\Magento\Catalog\Model\Product $product)
    {
        return $this->catHeirarchy->getCategoryHierarchyByProduct($product);
    }

    /**
     * Return an array of images for product
     *
     * @param \Magento\Catalog\Model\Product $product
     * @return array
     */
    public function getProductImages(\Magento\Catalog\Model\Product $product)
    {
        $imagesItems = [];
        $images = $product->getMediaGalleryImages();
        if (!$images instanceof \Magento\Framework\Data\Collection) {
            return $images;
        }
        foreach ($images as $image) {
            $galleryImagesConfig = $this->getGalleryImagesConfig()->getItems();
            foreach ($galleryImagesConfig as $imageConfig) {
                $image->setData(
                    $imageConfig->getData('data_object_key'),
                    $this->imageUrlBuilder->getUrl($image->getFile(), $imageConfig['image_id'])
                );
            }
        }

        foreach ($images as $image) {
            $imagesItems[] = $image->getData('medium_image_url');
        }

        return $imagesItems;
    }

     /**
     * Returns image gallery config object
     *
     * @return Collection
     */
    private function getGalleryImagesConfig()
    {
        if (false === $this->hasData('gallery_images_config')) {
            $galleryImageConfig = $this->galleryImagesConfigFactory->create($this->galleryImagesConfig);
            $this->setData('gallery_images_config', $galleryImageConfig);
        }

        return $this->getData('gallery_images_config');
    }

    public function getProductSpecs($product)
    {
        $attributes = $product->getAttributes();
        $categoryIds = $this->getCategoryIdsById($product->getId());
        $data = [];

        if (!empty($categoryIds)) {
            $categorySpecs = $this->getCategorySpecs();

            foreach ($categorySpecs as $parentCategoryId => $atrributeCodes) {
                if (in_array($parentCategoryId, $categoryIds)) {
                    $atrributeCodesConf = explode(',', $atrributeCodes);
                    foreach ($atrributeCodesConf as $attributeCode) {
                        foreach ($attributes as $attribute) {
                            if ($attribute->getAttributeCode() == $attributeCode) {
                                $value = $attribute->getFrontend()->getValue($product);

                                if ($value instanceof Phrase) {
                                    $value = (string)$value;
                                }

                                if (is_string($value) && strlen(trim($value))) {
                                    $value = $this->attributeHelper->productAttribute($product, $value, $attributeCode);
                                    $data[$attribute->getAttributeCode()] = [
                                        'label' => $attribute->getStoreLabel(),
                                        'value' => $value,
                                        'code' => $attribute->getAttributeCode(),
                                    ];
                                }
                            }
                            
                        }
                    }
                }
            }
        }

        return $data;
    }

    private function getCategorySpecs()
    {
        $confSettings = $this->scopeConfig->getValue(
            self::CATEGORY_SPECS_PATH,
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
        );
        $info = [];
        if ($confSettings) {
            $catSpecsConfig = $this->serializer->unserialize($confSettings);

            $info = [];
            foreach ($catSpecsConfig as $config) {
                $info[$config['parent_category_id']] = $config['attribute_codes'];
            }
        }
        
        return $info;
    }

    private function getCategoryIdsById($id)
    {
        $connection = $this->resource->getConnection();
        $productTable = $this->resource->getTableName('catalog_product_entity');
        $categoryProductTable = $this->resource->getTableName('catalog_category_product');

        $query = "SELECT ccp.category_id FROM $categoryProductTable ccp
                  INNER JOIN $productTable cpe ON ccp.product_id = cpe.entity_id
                  WHERE cpe.entity_id = :entity_id";

        return $connection->fetchCol($query, ['entity_id' => $id]);
    }
}
