<?php

namespace FiloBlu\Refilo\Remote\Entity\Provider;

use FiloBlu\Refilo\Remote\Entity\Category;
use FiloBlu\Refilo\Remote\Entity\EntityProviderInterface;
use FiloBlu\Refilo\Remote\Entity\MagentoToRefiloCategoryAdapter;
use LogicException;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Api\Data\CategoryInterface;
use Magento\Catalog\Model\ResourceModel\Category\Collection;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Api\Data\WebsiteInterface;
use Psr\Log\LoggerInterface;

/**
 * Class CategoryProvider
 * @package FiloBlu\Refilo\Remote\Entity\Provider
 */
class CategoryProvider extends AbstractFromCollectionProvider
{
    /**
     * @var Collection | null
     */
    protected $categoryCollection;
    /**
     * @var CollectionFactory
     */
    private $categoryCollectionFactory;
    /**
     * @var MagentoToRefiloCategoryAdapter
     */
    private $categoryAdapter;
    /**
     * @var CategoryRepositoryInterface
     */
    private $categoryRepository;
    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @param CollectionFactory $categoryCollectionFactory
     * @param MagentoToRefiloCategoryAdapter $categoryAdapter
     * @param ScopeConfigInterface $scopeConfig
     * @param CategoryRepositoryInterface $categoryRepository
     * @param LoggerInterface $logger
     */
    public function __construct(
        CollectionFactory $categoryCollectionFactory,
        MagentoToRefiloCategoryAdapter $categoryAdapter,
        ScopeConfigInterface $scopeConfig,
        CategoryRepositoryInterface $categoryRepository,
        LoggerInterface $logger
    ) {
        parent::__construct($scopeConfig);
        $this->categoryCollectionFactory = $categoryCollectionFactory;
        $this->categoryAdapter = $categoryAdapter;
        $this->categoryRepository = $categoryRepository;
        $this->logger = $logger;
    }


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

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

    /**
     * @return Collection
     * @throws LocalizedException
     */
    public function getCollection(): Collection
    {
        if ($this->categoryCollection === null) {
            $this->categoryCollection = $this->categoryCollectionFactory->create();
            $this->categoryCollection
                ->addAttributeToSelect('*')
                ->addAttributeToFilter('level', ['gteq' => 2]);
        }
        return $this->categoryCollection;
    }

    /**
     * @param StoreInterface $store
     * @return EntityProviderInterface
     * @throws LocalizedException
     * @throws NoSuchEntityException
     */
    public function forStore(StoreInterface $store): EntityProviderInterface
    {
        $this->categoryCollection = null;

        $this->getCollection()
            ->setStore($store->getId())
            ->joinUrlRewrite();

        $rootCategoryId = $store->getRootCategoryId();

        if ($rootCategoryId !== \Magento\Catalog\Model\Category::ROOT_CATEGORY_ID) {
            $this->getCollection()->addAttributeToFilter(
                'path',
                ['like' => sprintf('%s/%s/%%', \Magento\Catalog\Model\Category::TREE_ROOT_ID, $rootCategoryId)]
            );
        }

        return $this;
    }

    /**
     * @param WebsiteInterface $website
     * @return EntityProviderInterface
     */
    public function forWebsite(WebsiteInterface $website): EntityProviderInterface
    {
        throw new LogicException('Count not filter by website');
    }

    /**
     * @param $items
     * @return array
     * @throws LocalizedException
     */
    public function adapt($items)
    {
        $result = [];
        /** @var CategoryInterface $item */
        foreach ($items as $item) {
            $result[(int)$item->getId()] = $this->categoryAdapter->adapt($item, new Category());
        }

        return $result;
    }
}
