<?php

declare(strict_types=1);

namespace FiloBlu\Refilo\Remote\Entity\Provider;

use FiloBlu\Refilo\Remote\Entity\EntityProviderInterface;
use FiloBlu\Refilo\Remote\Entity\EntityProviderReaderHandlerInderface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\DataObject;

/**
 * Class BaseProvider
 * @package FiloBlu\Refilo\Remote\Entity\Provider
 */
abstract class BaseProvider implements EntityProviderInterface
{
    /** @var array|null */
    protected $ids;

    /** @var array */
    protected $items = [];

    /** @var EntityProviderReaderHandlerInderface|null */
    protected $readerHandler;

    /** @var DataObject */
    protected $readerHandlerArguments;

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

    /** @var int */
    private $pageSize;

    /**
     * AbstractFromCollectionProvider constructor.
     * @param ScopeConfigInterface $scopeConfig
     */
    public function __construct(
        ScopeConfigInterface $scopeConfig
    ) {
        $this->scopeConfig = $scopeConfig;
    }

    /**
     * @return mixed|void
     */
    #[\ReturnTypeWillChange]
    public function current()
    {
        return current($this->items);
    }

    /**
     * @return mixed|void
     */
    #[\ReturnTypeWillChange]
    public function next()
    {
        return next($this->items);
    }

    /**
     * @return bool|float|int|string|null
     */
    #[\ReturnTypeWillChange]
    public function key()
    {
        return key($this->items);
    }

    /**
     * @return bool|mixed
     */
    #[\ReturnTypeWillChange]
    public function valid()
    {
        return current($this->items);
    }

    /**
     * @param EntityProviderReaderHandlerInderface $handler
     * @param DataObject|null $arguments
     * @return EntityProviderInterface
     */
    public function attachReaderHandler(EntityProviderReaderHandlerInderface $handler, DataObject $arguments = null): EntityProviderInterface
    {
        $this->readerHandler = $handler;
        $this->readerHandlerArguments = $arguments ?: new DataObject();
        return $this;
    }

    /**
     * @return EntityProviderReaderHandlerInderface
     */
    public function detachReaderHandler(): EntityProviderReaderHandlerInderface
    {
        $handler = $this->readerHandler;
        $this->readerHandler = null;
        return $handler;
    }

    /**
     * @return EntityProviderReaderHandlerInderface|null
     */
    public function getReadHandler()
    {
        return $this->readerHandler;
    }

    /**
     * @return bool
     */
    public function hasReadHandler(): bool
    {
        return $this->readerHandler !== null;
    }

    /**
     * @return DataObject
     */
    public function getReadHandlerArguments()
    {
        return $this->readerHandlerArguments;
    }

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

    /**
     * @return int
     */
    public function getBulkSize(): int
    {
        if ($this->pageSize === null) {
            $pageSize = (int)$this->scopeConfig->getValue('sync/data/index_bulk_size');
            $this->pageSize = ($pageSize > 0) ? $pageSize : 500;
        }

        return $this->pageSize;
    }

    /**
     * @return EntityProviderInterface
     */
    public function prepare(): EntityProviderInterface
    {
        return $this;
    }

    /**
     * @return EntityProviderInterface
     */
    abstract public function release(): EntityProviderInterface;

}
