<?php

namespace Comitium5\DesignerBundle\Factory\Search\Suggest;

use Comitium5\DesignerBundle\ValueObjects\SearchOrderObject;
use Comitium5\DesignerBundle\ValueObjects\SearchQueryObject;
use Elastica\Aggregation\Terms;
use Elastica\Query;

/**
 * Class ElasticSearchQueryFactory
 *
 * @author David Carrascosa <david@bab-soft.com>
 * @package Comitium5\DesignerBundle\Factory\Search\Suggest
 */
class ElasticSearchQueryFactory
{
    /**
     * @param SearchQueryObject $searchQueryObject
     *
     * @return Query
     */
    public function create(SearchQueryObject $searchQueryObject): Query
    {
        $factory = new ElasticSearchBoolQueryFactory();

        $query = Query::create($factory($searchQueryObject));
        $query->setFrom(($searchQueryObject->getPage() - 1) * $searchQueryObject->getLimit());

        if ($searchQueryObject->getOrder() !== null) {
            $this->resolveOrder($query, $searchQueryObject->getOrder());
        }

        if ($searchQueryObject->getGroupBy() !== null) {
            $this->groupBy($query, $searchQueryObject->getGroupBy());
        }

        return $query;
    }

    /**
     * @param Query $query
     * @param SearchOrderObject $searchOrderObject
     */
    private function resolveOrder(Query $query, SearchOrderObject $searchOrderObject)
    {
        $query
            ->setSort([
                $searchOrderObject->getField() => [
                    'order' => $searchOrderObject->getSort()
                ]
            ]);
    }

    /**
     * @param Query $query
     * @param string $groupBy
     */
    private function groupBy(Query $query, string $groupBy): void
    {
        $aggregation = new Terms('types');

        $aggregation->setField($groupBy);

        $query->addAggregation($aggregation);
    }
}
