<?php

namespace FiloBlu\Flow\Model\Actions\From;

use FiloBlu\Flow\Model\Actions\From\AbstractWebsite;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductFactory;
use Magento\Store\Model\StoreRepository;
use Magento\Store\Model\WebsiteRepository;
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable as ProductTypeConfigurable;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Store\Model\ResourceModel\Website\CollectionFactory as WebsiteCollection;
use Magento\Catalog\Model\ResourceModel\Product\Action;
use FiloBlu\Flow\Helper\Product as HelperProduct;
use Magento\Framework\App\Config\ScopeConfigInterface;


/**
 * Class Reassignwebsite
 * @package FiloBlu\Flow\Model\Actions\From
 */
class Reassignwebsite extends AbstractWebsite
{
    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

    /**
     * @var WebsiteCollection
     */
    protected $websiteCollection;

    /**
     * @var Action
     */
    protected $_updateAction;

    /**
     * @var HelperProduct
     */
    protected $helperProduct;

    /**
     * @var ScopeConfigInterface
     */
    protected $scopeConfig;


    /**
     * @param ProductFactory $productFactory
     * @param WebsiteRepository $websiteRepository
     * @param ProductTypeConfigurable $productTypeConfigurable
     * @param ProductRepositoryInterface $productRepository
     * @param WebsiteCollection $websiteCollection
     * @param Action $action
     * @param HelperProduct $helperProduct
     * @param ScopeConfigInterface $scopeConfig
     */
    public function __construct(
        ProductFactory $productFactory,
        WebsiteRepository $websiteRepository,
        ProductTypeConfigurable $productTypeConfigurable,
        ProductRepositoryInterface $productRepository,
        WebsiteCollection $websiteCollection,
        Action $action,
        HelperProduct $helperProduct,
        ScopeConfigInterface $scopeConfig
    )
    {
        $this->productRepository = $productRepository;
        $this->websiteCollection = $websiteCollection;
        $this->_updateAction = $action;
        $this->helperProduct = $helperProduct;
        $this->scopeConfig = $scopeConfig;
        parent::__construct($productFactory, $websiteRepository, $productTypeConfigurable);
    }


    /**
     * @param $prod
     * @param $value
     * @param $storeId
     * @return false|void
     */
    public function process($prod, $value, $storeId)
    {
        if(!$value) {
            return false;
        }

        $websites = explode(',', str_replace('|', ',', $value));
        if (count($websites) === 0) {
            return false;
        }

        $websiteToProcess = $this->getNormalizedWebsiteArray($websites);

        if (count($websiteToProcess)) {
            $product_id = $this->productFactory->create()->getIdBySku($prod->getSku());
            $product = $this->productFactory->create()->setStoreId(0)->load($product_id);
            $oldWebsites = $product->getWebsiteIds();

            $productFromRepository = $this->productRepository->get($product->getSku());
            $productFromRepository->setWebsiteIds(array());
            $productFromRepository->setWebsiteIds($websiteToProcess);
            $attributeToExclude = $this->helperProduct->getAttributesExcludedToChangeWebsite();
            if(!empty($attributeToExclude)) {
                foreach ($attributeToExclude as $attributeCode) {
                    $productFromRepository->setData($attributeCode, NULL);
                }
            }
            $productFromRepository->save();

            $collection = $this->websiteCollection->create();
            $collection->addFieldToFilter('website_id', [
                    'in' => $oldWebsites]
            );
            $adminLocal = $this->scopeConfig->getValue('general/locale/code', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, 0);
            $updateLocal = [];
            foreach ($collection as $ws) {
                $stores = $ws->getStores();
                foreach ($stores as $store) {
                    $localeStore = $this->scopeConfig->getValue('general/locale/code', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store->getStoreId());
                    if ($localeStore != $adminLocal && !isset($updateLocal[$localeStore])) {
                        $updateLocal[$localeStore] = $store->getStoreId();
                    }
                }
            }

            $finalCollection = $this->websiteCollection->create();
            $finalCollection->addFieldToFilter('website_id', [
                    'in' => $websiteToProcess]
            );
            foreach ($finalCollection as $ws) {
                $stores = $ws->getStores();
                foreach ($stores as $store) {
                    $localeStore = $this->scopeConfig->getValue('general/locale/code', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store->getStoreId());
                    if ($localeStore != $adminLocal && isset($updateLocal[$localeStore])) {
                        $swapProduct = $this->productFactory->create()->setStoreId($updateLocal[$localeStore])->load($product_id);
                        $data = $swapProduct->getData();
                        $attributes = $swapProduct->getAttributes();
                        $toUpdate = [];
                        foreach ($attributes as $a) {
                            if ($a->getIsGlobal() == 0 && isset($data[$a->getName()]) && !in_array($a->getAttributeCode(), $attributeToExclude)) {
                                $toUpdate[$a->getAttributeCode()] = $data[$a->getAttributeCode()];
                            }
                        }
                        $this->_updateAction->updateAttributes([$product_id], $toUpdate, $store->getStoreId());
                    }
                }
            }
        }
    }

    /**
     * @param $websites
     * @param $existingWebsites
     * @return array
     */
    protected function getFinalWebsiteArray($websites,$existingWebsites){
        return $websites;
    }
}
