<?php
namespace Newland\Toubiz\Poi\Neos\LinkHandler;

use Neos\ContentRepository\Domain\Model\NodeInterface;
use Neos\Flow\Mvc\Controller\ControllerContext;
use Newland\NeosCommon\LinkHandler\Domain\Model\Record;
use Newland\NeosCommon\LinkHandler\Handler\AbstractLinkHandler;
use Newland\Toubiz\Poi\Neos\Service\ArticleUrlService;
use Newland\Toubiz\Sync\Neos\Domain\Model\Article;
use Newland\Toubiz\Sync\Neos\Domain\Repository\ArticleRepository;
use Neos\Flow\Annotations as Flow;

class ArticleLinkHandler extends AbstractLinkHandler
{

    /**
     * @var ArticleRepository
     * @Flow\Inject()
     */
    protected $articleRepository;

    /**
     * @var ArticleUrlService
     * @Flow\Inject()
     */
    protected $articleUrlService;

    public function setLanguage(?string $language = null): void
    {
        $this->articleRepository->setLanguage($language);
        parent::setLanguage($language);
    }

    /**
     * Generates a record link for the given record.
     *
     * @param Record $record
     * @param ControllerContext $controllerContext
     * @param NodeInterface $contextNode
     * @param bool $absolute
     * @return string|null
     */
    public function generateRecordLink(
        Record $record,
        ControllerContext $controllerContext,
        NodeInterface $contextNode,
        bool $absolute
    ): ?string {
        if (!($record instanceof ArticleRecord)) {
            $record = $this->findByIdentifier($record->getId());
        }

        if ($record === null) {
            return null;
        }

        return $this->articleUrlService->generateUrl(
            $record->getArticle(),
            $controllerContext,
            $contextNode
        );
    }

    /**
     * @param string $recordIdentifier
     * @return ArticleRecord|null
     */
    public function findByIdentifier(string $recordIdentifier): ?Record
    {
        return $this->articleToRecord(
            $this->articleRepository
                ->findOneBy([ 'Persistence_Object_Identifier' => $recordIdentifier ])
        );
    }

    /**
     * @param string $searchTerm
     * @return Record[]
     */
    public function findBySearchTerm(string $searchTerm): array
    {
        $query = $this->articleRepository->createQueryBuilder('article');
        $query->where($query->expr()->like('article.name', ':searchTerm'));
        $query->setParameter('searchTerm', '%' . $searchTerm . '%');
        $query->setMaxResults(10);
        return array_map(
            [ $this, 'articleToRecord' ],
            $query->getQuery()->execute()
        );
    }

    private function articleToRecord(Article $article = null)
    {
        if ($article === null) {
            return null;
        }

        return new ArticleRecord($article);
    }
}
