<?php

namespace Internetgalerie\IgDatapoolFe\Domain\Repository;

use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use Internetgalerie\IgDatapoolFe\Services\SearchLogicService;
use Internetgalerie\IgDatapoolFe\ViewHelpers\SearchFormViewHelper;
use Internetgalerie\IgDatapoolFe\ViewHelpers\SortHeaderViewHelper;

class Repository extends \TYPO3\CMS\Extbase\Persistence\Repository
{
    /**
     * Desc and asc shortcuts
     */
    public const ORDER_DESC = QueryInterface::ORDER_DESCENDING;
    public const ORDER_ASC = QueryInterface::ORDER_ASCENDING;

    /**
     * @var SearchLogicService
     */
    protected $searchLogicService;

    /**
     * @param SearchLogicService $searchLogicService
     */
    public function injectSearchLogicService(SearchLogicService $searchLogicService): void
    {
        $this->searchLogicService = $searchLogicService;
    }

    public function initializeObject(): void
    {
        $this->searchLogicService ??= GeneralUtility::makeInstance(SearchLogicService::class);
    }
    /**
     * find All Ordered By
     *
     * @param $attr      string attribute to order
     * @param $direction int 0: acsending, 1:descending
     */
    public function findAllOrderedBy($attr, $direction = 0)
    {
        $order = [$attr => $direction ? QueryInterface::ORDER_DESCENDING : QueryInterface::ORDER_ASCENDING];
        $query = $this->createQuery();
        $result = $query->setOrderings($order)->executeQuery();
        return $result;
    }

    /**
     * find all elements that match the default searchlogic,
     * i.e. all formfield names have to be equal to the model's property names
     */
    public function findWithSearch()
    {
        $query = $this->createQuery();
        // apply the default search logic
        // initialize the search logic service and alias it as $s
        $s = $this->initSearch($query);
        // apply the default search->argumentName equals propertyName
        $s->apply(null);

        //set auto sorting
        $this->initAutoSorting($query);

        //exec and return
        return $query->executeQuery();
    }

    /**
     * Initializes the serach logic on a query
     */
    protected function initSearch(QueryInterface $query)
    {
        //register in the viewhelper, that the search was initialized.
        SearchFormViewHelper::$isInitializedInQuery = true;
        $this->searchLogicService->bind($query);
        return $this->searchLogicService;
    }

    /**
     * initializes the autosorting on a query
     */
    protected function initAutoSorting(QueryInterface $query)
    {
        //register in the viewhelper, that autosorting is initializd
        SortHeaderViewHelper::$isInitializedInQuery = true;
        $sorting = $this->searchLogicService->getAutoSorting();
        if ($sorting != null) {
            $query->setOrderings($sorting);
        }
    }

    /**
     * Demo Functions
     */
    public function findWithSearchLogic___()
    {
        die('This is just a demo, implement your own method!');

        $query = $this->createQuery();

        // initialize the search logic service and alias it as $s
        $s = $this->initSearch($query);

        // build logic and apply it to the query
        $s->apply($s->_and($s->greaterThan('geburtsdatum', 'bli'), $s->like('name', 'blu')));

        //execute
        return $query->execute();
    }

    public function findWithOldSearchLogic___()
    {
        die('This is just a demo, implement your own method!');
        $query = $this->createQuery();

        // initialize the search logic service and alias it as $s
        $s = $this->initSearch($query);

        $searchSQL = $s->yesImReallySureThatIWantToUseTheDeprecatedSearchLogic(
            '
	<searchRules>
		<AND0>
			<field1>
				<attr>kanton</attr>
				<formfield>kanton</formfield>
				<operation>=</operation>
			</field1>
			<OR2>
				<field3>
					<attr>praxisname</attr>
					<formfield>keyword</formfield>
					<operation>parse</operation>
				</field3>
				<field4>
					<attr>tierarzt</attr>
					<formfield>keyword</formfield>
					<operation>parse</operation>
				</field4>
			</OR2>
		</AND0>
	</searchRules>'
        );
        if ($searchSQL) {
            $searchSQL = 'WHERE ' . $searchSQL;
        }

        //execute
        return $query->statement('SELECT * FROM tx_extension_domain_model_stuff ' . $searchSQL);
    }
}
