<?php declare(strict_types=1);

namespace Newland\NeosFiltering\Items;

use Doctrine\ORM\Query\Expr;
use Newland\Contracts\Neos\Filter\DataSourcedFilterItem;
use Newland\Contracts\Neos\Filter\Expression;
use Newland\Contracts\Neos\Filter\FilterItem;
use Newland\Contracts\Neos\Filter\ProvidesHiddenFieldsIfObstructed;
use Newland\Contracts\Neos\Filter\QueryBoundFilterItem;
use Newland\Contracts\Neos\Filter\StatusIndicatingFilterItem;
use Newland\Contracts\Neos\Filter\TitledFilterItem;
use Newland\NeosFiltering\Service\DataSourceHelper;
use Newland\NeosFiltering\StatusIndicator\StatusIndicator;
use Newland\NeosFiltering\Traits\FilterItemCommon;
use Newland\NeosFiltering\Traits\HasDataSource;
use Newland\NeosFiltering\Traits\HasQueryString;
use Newland\NeosFiltering\Traits\HasTitle;
use Newland\NeosFiltering\Traits\HasVisibleState;
use Newland\NeosFiltering\Traits\NeedsDatabaseColumn;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;

/**
 * Select box: Allows the user to select a single value from a drop-down.
 */
class SelectBox implements
    FilterItem,
    QueryBoundFilterItem,
    DataSourcedFilterItem,
    TitledFilterItem,
    StatusIndicatingFilterItem,
    ProvidesHiddenFieldsIfObstructed
{
    use FilterItemCommon,
        HasTitle,
        NeedsDatabaseColumn,
        HasDataSource,
        HasQueryString,
        HasVisibleState;

    public function setState($state): void
    {
        $state = DataSourceHelper::extractValidDataSourceOptionsBasedOnStateStrings(
            $this->getDataFromDataSource(),
            (array) $state
        );
        $this->state = $state[0] ?? null;
    }

    public function queryExpression(Expr $expr): Expression
    {
        $this->throwIfNoDatabaseColumnDeclared();
        $this->throwIfNoQueryString();
        if (empty($this->state)) {
            return Expression::empty();
        }

        return Expression::where(
            $expr->eq($this->databaseColumn, $expr->literal($this->state['value']))
        );
    }

    public function render(RenderingContextInterface $renderingContext)
    {
        $view = $this->initializeView();
        $view->assign('options', $this->getDataFromDataSource());
        return $view->render('SelectBox');
    }


    /** @return StatusIndicator[] */
    public function getStatusIndicators(): array
    {
        if (empty($this->state)) {
            return [];
        }

        $indicator = new StatusIndicator();
        $indicator->setId($this->getId());
        $indicator->setTitle($this->state['label']);
        return [ $indicator ];
    }
}
