<?php

namespace Comitium5\DesignerBundle\UseCase\Search;

use Comitium5\DesignerBundle\Repository\Search\ExternalDbRepository;
use Comitium5\DesignerBundle\ValueObjects\ExternalDbResultObject;
use ForceUTF8\Encoding;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * Class ExternalDbSuggestSearchUseCase
 *
 * @author David Carrascosa <david@bab-soft.com>
 * @package Comitium5\DesignerBundle\UseCase\Search
 */
class ExternalDbSuggestSearchUseCase
{
    /**
     * @var ExternalDbRepository
     */
    private $repository;

    /**
     * @var mixed
     */
    private $suggestQuery;

    /**
     * @var string
     */
    private $term;

    /**
     * ExternalDbSuggestSearchUseCase constructor.
     *
     * @param ExternalDbRepository $repository
     * @param string $suggestQuery
     * @param string $term
     *
     * @throws \Exception
     */
    public function __construct(
        ExternalDbRepository $repository,
        string $suggestQuery,
        string $term
    ) {
        $this->repository = $repository;
        $this->suggestQuery = json_decode($suggestQuery, true);
        $this->term = $term;

        $this->validateSuggestQuery();
    }

    /**
     * @return JsonResponse
     * @throws \Exception
     */
    public function __invoke(): JsonResponse
    {
        $results = $this
            ->repository
            ->search(
                $this->term,
                $this->suggestQuery
            );

        return new JsonResponse(
            $this->serialize($results),
            $results->getStatus()
        );
    }

    /**
     * @throws \Exception
     */
    protected function validateSuggestQuery(): void
    {
        if (
            !isset($this->suggestQuery["query"]) ||
            !isset($this->suggestQuery["text_key"]) ||
            !isset($this->suggestQuery["id_key"])
        ) {
            throw new \Exception("query, text_key and id_key keys must be provided");
        }
    }

    /**
     * @param ExternalDbResultObject $results
     *
     * @return array|array[]
     * @throws \Exception
     */
    protected function serialize(ExternalDbResultObject $results): array
    {
        if ($results->getStatus() === JsonResponse::HTTP_BAD_REQUEST) {
            return [];
        }

        $data = [
            'results' => []
        ];

        $textKey = $this->suggestQuery["text_key"];
        foreach ($results->getResults() as $result) {
            if (!empty($result[$textKey])) {
                $result["text"] = Encoding::toUTF8($result[$textKey]);
                unset($result[$textKey]);
                $data['results'][] = $result;
            }
        }

        return $data;
    }
}