<?php

namespace IQDEV\ElasticSearch;

use Elastic\Elasticsearch\Client;
use Elastic\Elasticsearch\Exception\ClientResponseException;
use Elastic\Elasticsearch\Exception\ServerResponseException;
use IQDEV\ElasticSearch\Converter\Request\CriteriaToRequest;
use IQDEV\ElasticSearch\Converter\Result\EsResponseToResult;
use IQDEV\ElasticSearch\Criteria\Criteria;

class SearchService implements Searchable
{
    private CriteriaToRequest $criteriaToRequest;
    private EsResponseToResult $esResponseToResult;

    public function __construct(
        private Client $esClient,
        private Configuration $configuration
    ) {
        $this->criteriaToRequest = new CriteriaToRequest($this->configuration);
        $this->esResponseToResult = new EsResponseToResult();
    }

    /**
     * @throws ServerResponseException
     * @throws ClientResponseException
     */
    public function search(Criteria $criteria): Result
    {
        $request = $this->criteriaToRequest->fromCriteria($criteria);

        $response = $this->esClient->search([
            'index' => $this->configuration->getIndexName(),
            'body' => $request->es(),
        ]);

        return $this->esResponseToResult->fromResponse($response, $this->configuration);
    }
}