<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Remote\Entity\Provider;

use FiloBlu\Refilo\Helper\Catalog\ProductAttributeHelper;
use FiloBlu\Refilo\Remote\Entity\Attribute;
use FiloBlu\Refilo\Remote\Entity\EntityProviderInterface;
use LogicException;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Api\Data\WebsiteInterface;

use function count;
use function in_array;

/**
 * Class AttributeProvider
 * @package FiloBlu\Refilo\Remote\Entity\Provider
 */
class ProductAttributeProvider extends BaseProvider
{
    /**
     * @var ProductAttributeHelper
     */
    protected $productAttributeHelper;

    /**
     * @var StoreInterface|null
     */
    protected $store;

    /**
     * ProductAttributeProvider constructor.
     * @param ProductAttributeHelper $productAttributeHelper
     * @param ScopeConfigInterface $scopeConfig
     */
    public function __construct(
        ProductAttributeHelper $productAttributeHelper,
        ScopeConfigInterface $scopeConfig
    ) {
        parent::__construct($scopeConfig);
        $this->productAttributeHelper = $productAttributeHelper;
    }

    /**
     *
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    #[\ReturnTypeWillChange]
    public function rewind()
    {
        $attributes = $this->productAttributeHelper->getAttributes()[$this->store->getId()];

        foreach ($attributes as $code => $data) {
            $attribute = new Attribute();
            $attribute->setId($code);
            if (in_array($data['type'], ['select', 'multiselect'])) {
                foreach ($data['options'] as $key => $option) {
                    $data['options'][$key]['code'] = $this->productAttributeHelper->getAdminValue(
                        $code,
                        $option['key']
                    );
                }
            }
            $attribute->addData($data);
            if (in_array($data['type'], ['select', 'multiselect'])) {
                foreach ($data['options'] as $key => $option) {
                    $data['options'][$key]['code'] = $this->productAttributeHelper->getAdminValue(
                        $code,
                        $option['key']
                    );
                }
            }
            $this->items[$code] = $attribute;
        }

        if (!$this->hasReadHandler()) {
            return;
        }

        $this->getReadHandler()->onRead($this->items, count($attributes), $this->getReadHandlerArguments());
    }

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

    /**
     * @param StoreInterface $store
     * @return $this|EntityProviderInterface
     */
    public function forStore(StoreInterface $store): EntityProviderInterface
    {
        $this->store = $store;
        return $this;
    }

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

    /**
     * @return \Generator
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function toGenerator(): \Generator
    {
        $attributes = $this->productAttributeHelper->getAttributes()[$this->store->getId()];

        foreach ($attributes as $code => $data) {
            $attribute = new Attribute();
            $attribute->setId($code);
            if (in_array($data['type'], ['select', 'multiselect'])) {
                foreach ($data['options'] as $key => $option) {
                    $data['options'][$key]['code'] = $this->productAttributeHelper->getAdminValue(
                        $code,
                        $option['key']
                    );
                }
            }
            $attribute->addData($data);
            if (in_array($data['type'], ['select', 'multiselect'])) {
                foreach ($data['options'] as $key => $option) {
                    $data['options'][$key]['code'] = $this->productAttributeHelper->getAdminValue(
                        $code,
                        $option['key']
                    );
                }
            }

            yield $attribute;
        }
    }

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