<?php

namespace FiloBlu\Flow\Model\From\Entity;

use Exception;
use FiloBlu\Flow\Helper\LoggerProvider;
use Magento\Catalog\Model\Product\Action;
use Magento\Catalog\Model\ProductFactory;
use Magento\Eav\Model\Entity\Attribute\Source\BooleanFactory;
use Magento\Eav\Model\Entity\AttributeFactory;
use Magento\Eav\Model\Entity\TypeFactory;
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\CollectionFactory;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\Registry;

/**
 * Class Product
 * @package FiloBlu\Flow\Model\From\Entity
 */
class Product extends AbstractEntity
{
    /**
     * @var Action
     */
    protected $productAction;

    /**
     * @var array
     */
    protected $attributeMappedByValue;


    /**
     * Product constructor.
     * @param Registry $registry
     * @param ProductFactory $productFactory
     * @param \FiloBlu\Flow\Helper\Product $helperProduct
     * @param \FiloBlu\Flow\Helper\Attribute $helperAttribute
     * @param LoggerProvider $loggerProvider
     * @param AttributeFactory $attributeFactory
     * @param CollectionFactory $attributeOptionCollectionFactory
     * @param ObjectManagerInterface $objectManager
     * @param TypeFactory $entityTypeFactory
     * @param Action $productAction
     * @param BooleanFactory $booleanFactory
     * @param array $attributeMappedByValue
     * @param array $data
     */
    public function __construct(
        Registry $registry,
        ProductFactory $productFactory,
        \FiloBlu\Flow\Helper\Product $helperProduct,
        \FiloBlu\Flow\Helper\Attribute $helperAttribute,
        LoggerProvider $loggerProvider,
        AttributeFactory $attributeFactory,
        CollectionFactory $attributeOptionCollectionFactory,
        ObjectManagerInterface $objectManager,
        TypeFactory $entityTypeFactory,
        Action $productAction,
        BooleanFactory $booleanFactory,
        $attributeMappedByValue = [],
        array $data = []
    ) {
        $this->productAction = $productAction;
        $this->attributeMappedByValue = $attributeMappedByValue;

        parent::__construct($registry,
            $productFactory,
            $helperProduct,
            $helperAttribute,
            $loggerProvider,
            $attributeFactory,
            $attributeOptionCollectionFactory,
            $objectManager,
            $entityTypeFactory,
            $booleanFactory,
            $data);
    }

    /**
     * @return void
     * @throws Exception
     */
    protected function setObjectAttributeValue()
    {
        if (!$this->getObjectId()) {
            throw new Exception(sprintf('No id found for model %s with given identifier %s', $this->getEntityModel(), $this->entityIdentifier));
        }

        $attribute_code = $this->getAttribute()->getAttributeCode();

        $pIds = [$this->getObjectId()];

        $fatherProductsIds = $this->helperProduct->getParentProductsIds($pIds);
        $attributesToCopy = $this->registry->registry('attribute_configurable_copy');
        if (!empty($fatherProductsIds) && in_array($attribute_code, $attributesToCopy, false)) {
            $pIds = array_merge($pIds, $fatherProductsIds);
        }

        $parentGrouped = $this->helperProduct->getGroupedIdByChildId($this->getObjectId());
        if($parentGrouped) {
            $parentGroupedId = [$parentGrouped->getId()];
            $attributesCopyToGrouped = $this->helperProduct->getSimpleAttributesSyncToGrouped();
            if(in_array($attribute_code, $attributesCopyToGrouped, false)) {
                $pIds = array_merge($pIds, $parentGroupedId);
            }
        }

        $attributeValue = $this->getAttributeValue();
        $attributesData = [$attribute_code => $attributeValue];

        if ($attribute_code !== 'sku') {
            $this->productAction->updateAttributes($pIds, $attributesData, $this->storeId);
        }
    }

    /**
     * @return bool|mixed|null
     * @throws Exception
     */
    public function getObjectId()
    {
        if ($this->_objectEntityId === null) {
            $this->_objectEntityId = ObjectManager::getInstance()->create($this->getEntityModel())->getIdBySku($this->entityIdentifier);
            if (empty($this->_objectEntityId)) {
                $this->_objectEntityId = false;
            }
        }

        return $this->_objectEntityId;
    }

    /**
     * @return \Magento\Catalog\Model\Product|null
     * @throws Exception
     */
    protected function getObject()
    {
        if ($this->objectEntity === null) {
            if (!$this->getObjectId()) {
                throw new Exception('No id found for model ' . $this->getEntityModel() . ' with given identifier ' . $this->entityIdentifier);
            }
            $_prod_sku = $this->productFactory->create()->getIdBySku($this->entityIdentifier);
            $this->objectEntity = $this->productFactory->create()->setStoreId($this->storeId)->load($_prod_sku);
            if (!$this->objectEntity->getId()) {
                throw new Exception('No instance found for model ' . $this->getEntityModel() . ' with id ' . $this->getObjectId());
            }
        }
        return $this->objectEntity;
    }
}
