<?php

namespace Comitium5\DesignerBundle\Manager;

use Comitium5\DesignerBundle\Form\Type\SearchFormType;
use Comitium5\DesignerBundle\Model\Interfaces\SearchableRepositoryInterface;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Class SearchListManager
 *
 * @author Carles Gómez <carles@bab-soft.com>
 * @package Comitium5\DesignerBundle\Manager
 */
class SearchListManager
{
    /**
     * @var FormFactory $formFactory
     */
    private $formFactory;

    /**
     * @var SearchableRepositoryInterface $searchableRepository
     */
    private $searchableRepository;

    /**
     * @var RequestStack
     */
    private $requestStack;

    /**
     * @param FormFactory  $formFactory
     * @param RequestStack $requestStack
     */
    public function __construct(FormFactory $formFactory, RequestStack $requestStack)
    {
        $this->formFactory = $formFactory;
        $this->requestStack = $requestStack;
    }

    /**
     * @param SearchableRepositoryInterface|null $repository
     * @param Request $request
     * @param array $params
     * @param null $searchText
     * @return mixed
     * @throws \Exception
     */
    public function handleSimpleSearch(
        SearchableRepositoryInterface $repository = null,
        Request $request,
        array $params = [],
        $searchText = null
    ) {
        $repository = $repository === null ? $this->searchableRepository : $repository;

        if (!$repository) {
            throw new \Exception('Searchable respository must be defined');
        }

        $form = $this->formFactory->create(SearchFormType::class, null, [
            'method' => $request->getMethod(),
        ]);

        $form->handleRequest($this->requestStack->getMasterRequest());

        $search = $form->get('search')->getData();

        if ($search === null) {
            $search = $searchText;
        }

        return $repository->search($search, $params);
    }

    /**
     * @param SearchableRepositoryInterface $repository
     * @param Form                          $form
     * @param Request                       $request
     * @param array                         $params
     *
     * @return mixed
     */
    public function handleAdvancedSearch(
        SearchableRepositoryInterface $repository,
        Form $form,
        Request $request,
        array $params = []
    )
    {
        $form->handleRequest($this->requestStack->getMasterRequest());

        //$requestParams = $request->get($form->getName(), []);
        $requestParams = $form->getData();

        $requestParams = $requestParams !== null ? $requestParams : [];

        $term = $form->get('search')->getData();

        $params = $requestParams + $params;

        return $repository->search($term, $params);
    }

    /**
     * @return FormFactory
     */
    public function getFormFactory()
    {
        return $this->formFactory;
    }

    /**
     * @param FormFactory $formFactory
     */
    public function setFormFactory($formFactory)
    {
        $this->formFactory = $formFactory;
    }

    /**
     * @return mixed
     */
    public function getSearchableRepository()
    {
        return $this->searchableRepository;
    }

    /**
     * @param mixed $searchableRepository
     *
     * @return $this
     */
    public function setSearchableRepository($searchableRepository)
    {
        $this->searchableRepository = $searchableRepository;

        return $this;
    }
}
