<?php declare(strict_types=1);

namespace Newland\NeosFiltering\Items;

use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
use Newland\Contracts\Neos\Filter\Expression;
use Newland\Contracts\Neos\Filter\FilterItem;
use Newland\Contracts\Neos\Filter\ModifiesDatabaseQueryDirectly;
use Newland\Contracts\Neos\Filter\QueryBoundFilterItem;
use Newland\NeosFiltering\Traits\FilterItemCommon;
use Newland\NeosFiltering\Traits\HasInvisibleState;
use Newland\NeosFiltering\Traits\HasQueryString;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;

/**
 * Renders a hidden input field used to carry pagination information.
 */
class PaginationInput implements FilterItem, QueryBoundFilterItem, ModifiesDatabaseQueryDirectly
{
    use FilterItemCommon,
        HasQueryString,
        HasInvisibleState;

    /**
     * @var bool
     */
    protected $isEnabled = true;

    public function modifyDatabaseQuery(QueryBuilder $query): QueryBuilder
    {
        if (!$this->isEnabled) {
            return $query;
        }

        $pageSize = $this->configuration['pageSize'] ?? 10;
        $page = max((int) $this->state, 1);
        $offset = ($page - 1) * $pageSize;

        return $query
            ->setFirstResult($offset)
            ->setMaxResults($pageSize);
    }

    public function render(RenderingContextInterface $renderingContext)
    {
        if (!$this->isEnabled) {
            return null;
        }
        return $this->initializeView()->render('PaginationInput');
    }

    public function queryExpression(Expr $expr): Expression
    {
        return Expression::empty();
    }

    public function enablePagination(bool $enabled): void
    {
        $this->isEnabled = $enabled;
    }
}
