<?php declare(strict_types=1);

namespace Newland\Toubiz\Services\Neos\Search;

use Neos\Flow\Annotations as Flow;
use Newland\Contracts\Neos\Search\IndexerInterface;
use Newland\Contracts\Neos\Search\IndexRecordModification;
use Newland\Contracts\Neos\Search\ProgressHandler;
use Newland\Contracts\Neos\Search\SearchBackend;
use Newland\Toubiz\Sync\Neos\Domain\Model\Service;
use Newland\Toubiz\Sync\Neos\Domain\Repository\ServiceRepository;

class ServiceIndexer implements IndexerInterface
{
    /**
     * @var ServiceRepository
     * @Flow\Inject()
     */
    protected $serviceRepository;

    /** @var int|null */
    private $total;

    /** @var string[] */
    private $indexed = [];

    /** @var array */
    protected $configuration;

    public function index(array $scopesToIndex, SearchBackend $backend, ProgressHandler $progressHandler): void
    {
        $this->serviceRepository->withoutLanguageHandling(
            function () use ($scopesToIndex, $backend, $progressHandler) {
                $this->total = $this->serviceRepository->countAll();

                foreach ($this->serviceRepository->findAllIterator() as $services) {
                    foreach ($services as $service) {
                        $modification = $this->serviceToModification($service, $scopesToIndex);
                        $backend->createOrUpdateIndexEntry($modification);
                        $this->indexed[] = $modification->getIdentifier();
                        $progressHandler->informProgress('Services', \count($this->indexed), $this->total);
                    }
                }
            }
        );
    }

    public function postIndex(SearchBackend $backend): void
    {
        $backend->deleteObsoleteIndexEntries($this->indexed);
    }

    public function setConfiguration(array $configuration = []): void
    {
        $this->configuration = $configuration;
    }

    private function serviceToModification(Service $service, array $scopes): IndexRecordModification
    {
        return new IndexRecordModification(
            (string) $service->getPersistenceObjectIdentifier(),
            $service->getType(),
            $service->getName(),
            (string) $service->getDescription(),
            trim(implode(' ', $service->getBenefits())),
            $scopes,
            $service->getLanguage()
        );
    }
}
