<?php
namespace AppBundle\Utils\Services;


class AdSearcher
{

    protected $finder;

    /**
     * AdSearcher constructor.
     * @param $finder
     */
    public function __construct($finder)
    {
        $this->finder = $finder;
    }

    /**
     * @param $data
     * @param string $param
     * @return mixed|null
     */
    public function process($data, $param = 'lite')
    {
        if ($param == 'lite') {
            $ads = $this->searchLite($data);
        } elseif ($param == 'tag') {
            $ads = $this->searchTag($data);
        } else {
            return null;
        }
        return $ads;
    }

      /**
     * @param $data
     * @return mixed
     *
     * ElasticSearch query for ad search
     */
    public function searchTag($data)
    {
        $query = new \Elastica\Query();
        $boolQuery = new \Elastica\Query\BoolQuery();
        $fieldQuery = new \Elastica\Query\MultiMatch();
        if(isset($data['tag'])){
            $fieldQuery->setQuery($data['tag']);
            $fieldQuery->setFields(['publicTag']);
            //$fieldQuery->setFieldQuery('publicTag', $data['tag']);
            $boolQuery->addMust($fieldQuery);
        }
        $query->setQuery($boolQuery);
        $result = $this->finder->find($query);
        $ads = $this->filterStatus($result);

        return $ads;
    }

    /**
     * @param $data
     * @return mixed
     *
     * ElasticSearch query for ad search
     */
    public function searchLite($data)
    {
        $point = $this->getPoint($data);
        $query = new \Elastica\Query();
        if ($point != null) {
            $query->addSort(
                ['_geo_distance' => [
                    'location' => $point,
                    'order' => 'asc',
                    'unit' => 'km']
                ]
            );
        }
        $boolQuery = new \Elastica\Query\BoolQuery();
        $fieldQuery = new \Elastica\Query\MultiMatch();
        if(isset($data['job'])){
            $fieldQuery->setQuery($data['job']);
            $fieldQuery->setFields(['title', 'publicTag', 'company.brandname']);
            $boolQuery->addMust($fieldQuery);
        }
        
        if($data['contrat']){
            $fieldQueryContract = new \Elastica\Query\Match();
            $fieldQueryContract->setFieldQuery('contract_type', $data['contrat']);
            $boolQuery->addMust($fieldQueryContract);
        }

        $query->setQuery($boolQuery);
        $result = $this->finder->find($query);
        $ads = $this->filterStatus($result);
        return $ads;
    }

    /**
     * @param $data | form data
     * @return mixed | Array containing only lat/lon properties
     */
    public function getPoint($data)
    {
        $point = null;
        $location = json_decode($data['location'], true);
        if (is_array($location) && array_key_exists('gmap_address', $location)) {
            $point = $location['gmap_address']['geometry']['location'];
            if (array_key_exists('lng', $point)) {
                $point['lon'] = $point['lng'];
                unset($point['lng']);
            }
        }
        return $point;
    }

    /**
     * @param $result
     * @param string $status
     * @return array
     */
    public function filterStatus($result, $status = "PUBLISHED")
    {
        $ads = array();
        foreach ($result as $ad) {
            if ($ad->getStatus() == "PUBLISHED" && $ad->getIsPrivate() != true && $ad->getIsPromoted() != true) {
                $ads[] = $ad;
            }
        }
        return $ads;
    }

}