<?php declare(strict_types=1);

namespace Newland\Toubiz\Map\Neos\Tests\Unit\LinkHandler;

use Neos\ContentRepository\Domain\Model\Node;
use Neos\Flow\Tests\FunctionalTestCase;
use Newland\NeosCommon\Service\ControllerContextFactory;
use Newland\NeosTestingHelpers\InteractsWithNodes;
use Newland\Toubiz\Map\Neos\LinkHandler\FilterItemLinkHandler;

class FilterItemLinkHandlerTest extends FunctionalTestCase
{
    protected static $testablePersistenceEnabled = true;
    use InteractsWithNodes;

    /** @var FilterItemLinkHandler */
    protected $subject;

    /**
     * @var array<string, Node>
     */
    protected $nodes;

    public function setUp(): void
    {
        parent::setUp();
        $this->subject = $this->objectManager->get(FilterItemLinkHandler::class);

        $site = $this->initializeSite('foo');
        $this->nodes = $this->nodes([
            '/sites/foo' => ['nodeType' => 'Neos.NodeTypes:Page'],
            '/sites/foo/map' => ['nodeType' => 'Newland.Toubiz.Map.Neos:Map'],
            '/sites/foo/map/children' => ['nodeType' => 'Neos.Neos:ContentCollection'],
            '/sites/foo/map/children/foo' => ['properties' => ['title' => 'Foo'], 'nodeType' => 'Newland.Toubiz.Map.Neos:Map.FilterItem'],
            '/sites/foo/map/children/bar' => ['properties' => ['title' => 'Bar'], 'nodeType' => 'Newland.Toubiz.Map.Neos:Map.FilterItem'],
        ], ['site' => $site]);
    }

    public function testFindsFilterItemNodesWithMatchingTitle(): void
    {
        $result = $this->subject->findBySearchTerm('Foo');
        $this->assertCount(1, $result);
        $this->assertStringStartsWith('Foo', $result[0]->getTitle());
    }

    public function testDoesNotFindOtherNodeTypes(): void
    {
        $n = $this->initializeNode(
            '/sites/foo/something-else',
            $this->nodes['/sites/foo']->getWorkspace()->getName(),
            $this->nodes['/sites/foo']->getContext()->getCurrentSite(),
            ['title' => 'Foo'],
            'de',
            'Neos.NodeTypes:Text'
        );

        $result = $this->subject->findBySearchTerm('Foo');
        $identifiers = array_map(
            function ($record) {
                return $record->getId();
            },
            $result
        );
        $this->assertNotContains($n->getIdentifier(), $identifiers);
    }

    public function testFullWalkThrough(): void
    {
        // By editor in backend, only id gets saved
        $result = $this->subject->findBySearchTerm('Foo');
        $this->assertCount(1, $result);
        $id = $result[0]->getId();

        // In frontend: First get the record, then generate URL from it
        $record = $this->subject->findByIdentifier($id);
        $this->assertNotNull($record);
        $url = $this->subject->generateRecordLink(
            $record,
            $this->objectManager->get(ControllerContextFactory::class)->initializeFakeControllerContext($this->nodes['/sites/foo']),
            $this->nodes['/sites/foo'],
            true
        );

        $this->assertNotNull($url);
        $this->assertStringContainsString('#' . $id, $url);
    }
}
