<?php declare(strict_types=1);

namespace Newland\Toubiz\Poi\Neos\Tests\Unit\Search\Indexer;

use Neos\Flow\Tests\FunctionalTestCase;
use Newland\Contracts\Neos\Search\IndexRecordModification;
use Newland\Contracts\Neos\Search\SearchBackend;
use Newland\Contracts\Neos\Search\SearchRequest;
use Newland\Contracts\Neos\Search\SearchResultCollection;
use Newland\Toubiz\Poi\Neos\Search\Indexer\ArticleIndexer;
use Newland\Toubiz\Search\Neos\Progress\NullHandler;
use Newland\Toubiz\Sync\Neos\Tests\Factory\ArticleFactory;
use Newland\Toubiz\Sync\Neos\Tests\Factory\AttributeFactory;

class ArticleIndexerTest extends FunctionalTestCase implements SearchBackend
{
    protected static $testablePersistenceEnabled = true;

    protected $subject;

    /** @var ArticleFactory */
    protected $articleFactory;

    /** @var IndexRecordModification[] */
    protected $entries = [];

    public function setUp(): void
    {
        parent::setUp();
        $this->subject = $this->objectManager->get(ArticleIndexer::class);
        $this->articleFactory = new ArticleFactory($this->objectManager);
        $this->entries = [];
    }

    public function testIndexesArticle(): void
    {
        $this->articleFactory->create([
            'abstract' => '__SOME_ABSTRACT__',
            'description' => '__SOME_DESCRIPTION__',
            'name' => '__SOME_NAME__',
        ]);
        $this->subject->index($this, new NullHandler());

        $this->assertCount(1, $this->entries);
        $this->assertContains('__SOME_ABSTRACT__', $this->entries[0]->getContent());
        $this->assertContains('__SOME_DESCRIPTION__', $this->entries[0]->getContent());
        $this->assertContains('__SOME_NAME__', $this->entries[0]->getContent());
    }

    public function testIndexesAdditionalSearchString(): void
    {
        $this->articleFactory->create([
          'attributes' => [
              (new AttributeFactory($this->objectManager))->make([ 'name' => 'additionalSearchString', 'data' => '__ADDITIONAL__' ]),
          ]
      ]);

        $this->subject->index($this, new NullHandler());

        $this->assertCount(1, $this->entries);
        $this->assertContains('__ADDITIONAL__', $this->entries[0]->getContent());
    }

    public function testIndexesMultipleAdditionalSearchStrings(): void
    {
        $this->articleFactory->create([
          'attributes' => [
              (new AttributeFactory($this->objectManager))->make([ 'name' => 'additionalSearchString', 'data' => '__ADDITIONAL__' ]),
              (new AttributeFactory($this->objectManager))->make([ 'name' => 'additionalSearchString', 'data' => '__ANOTHER__' ]),
          ]
      ]);

        $this->subject->index($this, new NullHandler());

        $this->assertCount(1, $this->entries);
        $this->assertContains('__ADDITIONAL__', $this->entries[0]->getContent());
        $this->assertContains('__ANOTHER__', $this->entries[0]->getContent());
    }

    // Mock implementation of search backend
    public function setSource(string $source): void
    {
        // Mock implementation of SearchBackend
    }

    public function createOrUpdateIndexEntry(IndexRecordModification $modification): void
    {
        $this->entries[] = $modification;
    }

    public function afterIndexing(): void
    {
        // Mock implementation of SearchBackend
    }


    public function deleteObsoleteIndexEntries(array $identifiersToRetain): void
    {
        // Mock implementation of SearchBackend
    }

    public function search(SearchRequest $request): SearchResultCollection
    {
        // Mock implementation of SearchBackend
    }

    public function initialize(): void
    {
        // Mock implementation of SearchBackend
    }
}
