<?php
declare(strict_types=1);

namespace FiloBlu\Refilo\Remote\Entity\Provider;

use Exception;
use FiloBlu\Refilo\Helper\Catalog\ProductHelper;
use FiloBlu\Refilo\Remote\Entity\AbstractEntity;
use FiloBlu\Refilo\Remote\Entity\EntityProviderInterface;
use FiloBlu\Refilo\Remote\Entity\MagentoToDisabledRefiloProductAdapter;
use FiloBlu\Refilo\Remote\Entity\Product;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Product\Attribute\Source\Status as AttributeStatus;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Api\Data\WebsiteInterface;
use Magento\Store\Model\StoreManagerInterface;

/**
 * Class DisabledProductProvider
 * @package FiloBlu\Refilo\Remote\Entity\Provider
 */
class DisabledProductProvider extends AbstractFromCollectionProvider
{
    /**
     * @var CollectionFactory
     */
    private $productCollectionFactory;

    /**
     * @var WebsiteInterface
     */
    private $website;

    /**
     * @var StoreInterface
     */
    private $store;

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var ProductHelper
     */
    private $productHelper;

    /**
     * @var Collection
     */
    private $productCollection;

    /**
     * @var MagentoToDisabledRefiloProductAdapter
     */
    private $productAdapter;

    /**
     * @param ScopeConfigInterface $scopeConfig
     * @param StoreManagerInterface $storeManager
     * @param ProductHelper $productHelper
     * @param MagentoToDisabledRefiloProductAdapter $magentoToDisabledRefiloProductAdapter
     * @param CollectionFactory $productCollectionFactory
     */
    public function __construct(
        ScopeConfigInterface                  $scopeConfig,
        StoreManagerInterface                 $storeManager,
        ProductHelper                         $productHelper,
        MagentoToDisabledRefiloProductAdapter $magentoToDisabledRefiloProductAdapter,
        CollectionFactory                     $productCollectionFactory
    ) {
        parent::__construct($scopeConfig);
        $this->productCollectionFactory = $productCollectionFactory;
        $this->storeManager = $storeManager;
        $this->productHelper = $productHelper;
        $this->productAdapter = $magentoToDisabledRefiloProductAdapter;
    }

    /**
     * @param array $ids
     * @return EntityProviderInterface
     */
    public function withIds(array $ids): EntityProviderInterface
    {
        if (empty($ids)) {
            return $this;
        }

        $this->getCollection()->addFieldToFilter('entity_id', ['in' => $ids]);
        return $this;
    }

    /**
     * @return Collection
     */
    public function getCollection()
    {
        if ($this->productCollection === null) {
            $this->productCollection = $this->productCollectionFactory->create()
                ->addAttributeToSelect('url_key')
                ->addAttributeToSelect('status')
                ->addAttributeToSelect('name');
        }

        return $this->productCollection;
    }

    /**
     * @param $items
     * @return array
     * @throws Exception
     */
    public function adapt($items)
    {
        $output = [];
        /** @var ProductInterface $magentoProduct */
        foreach ($items as $magentoProduct) {
            $entityId = $magentoProduct->getEntityId();

            if ((int)$magentoProduct->getStatus() === AttributeStatus::STATUS_DISABLED) {
                $output[$entityId] = $this->productAdapter->adapt($magentoProduct, new Product());
                continue;
            }

            if (!$this->website) {
                continue;
            }

            if (!$this->productHelper->productBelongsTo($entityId, $this->website->getId())) {
                $output[$entityId] = $this->productAdapter->adapt($magentoProduct, new Product());
                continue;
            }

            // Fallback for updated products
            $output[$entityId] = new Product([AbstractEntity::ID => (int)$entityId]);
        }

        return $output;
    }

    /**
     * @param StoreInterface $store
     * @return EntityProviderInterface
     * @throws LocalizedException
     */
    public function forStore(StoreInterface $store): EntityProviderInterface
    {
        $this->store = $store;
        $this->website = $this->storeManager->getWebsite($store->getWebsiteId());
        return $this;
    }

    /**
     * @param WebsiteInterface $website
     * @return EntityProviderInterface
     */
    public function forWebsite(WebsiteInterface $website): EntityProviderInterface
    {
        $this->website = $website;
        return $this;
    }

    public function release(): EntityProviderInterface
    {
        $this->items = [];
        return $this;
    }
}
