<?php

namespace FiloBlu\Refilo\Remote\Entity\Provider;


/**
 * Class AbstractFromCollectionProvider
 * @package FiloBlu\Refilo\Remote\Entity\Provider
 */
abstract class AbstractFromCollectionProvider extends BaseProvider
{

    /**
     * @return bool|float|int|string|null
     */
    public function key()
    {
        if (!current($this->items)) {
            return null;
        }

        return current($this->items)->getId();
    }

    /**
     * @return bool
     */
    public function valid()
    {
        if ($this->getCollection()->getCurPage() < $this->getCollection()->getLastPageNumber()) {
            if (current($this->items) !== false) {
                return true;
            }

            $this->handleItems($this->getCollection()
                ->clear()
                ->setCurPage($this->getCollection()->getCurPage() + 1)
                ->getItems());

            return true;
        }

        return current($this->items) !== false;
    }

    abstract public function getCollection();

    /**
     *
     */
    public function handleItems($items)
    {
        $this->items = $this->adapt($items);

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

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

    /**
     * @param $items
     * @return mixed
     */
    abstract public function adapt($items);

    /**
     *
     */
    #[\ReturnTypeWillChange]
    public function rewind()
    {
        $this->handleItems($this->getCollection()
            ->clear()
            ->setPageSize($this->getBulkSize())
            ->setCurPage(1)
            ->getItems()
        );
    }

    /**
     * @return \Generator
     */
    public function toGenerator(): \Generator
    {
        $currentPage = 1;
        $pageSize = $this->getBulkSize();
        $collection = $this->getCollection()->clear()->setPageSize($pageSize)->setCurPage($currentPage);
        $lastPage = $collection->getLastPageNumber();

        while ($currentPage <= $lastPage) {

            $collection->setPageSize($pageSize);
            $collection->setCurPage($currentPage);

            foreach ($collection as $item) {
                $results = $this->adapt([$item]);
                foreach ($results as $result) {
                    yield $result;
                }
            }

            $collection->clear();
            $currentPage++;
        }
    }
}
