<?php
class SearchController extends BaseController
{

    public function search() {
        $params = $this->request->get();

        $params['limit'] = $this->getDefaultLimit($params);
        $params['offset'] = array_key_exists('offset', $params) ? $params['offset'] : 0;

        $validatedRequest = $this->validate(
            $params,
            [
                'q' => ['validators' => ['required']],
                'sector' => [],
                'category' => [],
                'substance' => [],
                'limit' => ['validators' => ['digit']],
                'offset' => ['validators' => ['digit']],
            ]
        );

        $options = [
            'limit' => (int) $validatedRequest['limit'],
            'offset' => (int) $validatedRequest['offset'],
        ];

        $filters = [];

        if($validatedRequest['sector'] != null) {
            $sectors = explode("|", $validatedRequest['sector']);
            foreach ($sectors as $idx => $value) {
                $sectors[$idx] = 'sector = "' . $value . '"';
            }
            $filters[] = '('.implode(" OR ", $sectors).')';
        }
        if($validatedRequest['category'] != null) {
            $categories = explode("|", $validatedRequest['category']);
            foreach ($categories as $idx => $value) {
                $categories[$idx] = 'category = "' . $value . '"';
            }
            $filters[] = '('.implode(" OR ", $categories).')';
        }
        if($validatedRequest['substance'] != null) {
            $substances = explode("|", $validatedRequest['substance']);
            foreach ($substances as $idx => $value) {
                $substances[$idx] = 'substance = "' . $value . '"';
            }
            $filters[] = '('.implode(" OR ", $substances).')';
        }

        if(count($filters) > 0)
            $options['filters'] = implode(" AND ", $filters);

        $meili = new MeiliSearchService($this);

        $searchResult = $meili->search($validatedRequest['q'], $options);

        //region save to popular search
        $today = date('Y-m-d');
        $popularData = MeilisearchPopularSearch::findFirst([
            'conditions' => 'LOWER(search_query) = ?0 AND search_date = ?1',
            'bind' => [
                strtolower($validatedRequest['q']),
                $today
            ]
        ]);
        if(empty($popularData)) {
            $popularData = new MeilisearchPopularSearch();
            $popularData->search_count = 0;
            $popularData->search_date = $today;
        }
        $popularData->search_query = strtolower($validatedRequest['q']);
        $popularData->search_count++;
        $popularData->save();

        //endregion

        return new SimpleResponse($searchResult == null ? null : (is_array($searchResult) ? $searchResult : $searchResult->toArray()));
    }

    public function popularSearch() {
        $data = MeilisearchPopularSearch::find([
            'conditions' => 'search_date = ?0',
            'bind' => [
                date('Y-m-d')
            ],
            'order' => 'search_count desc'
        ]);
        return new SimpleResponse($data);
    }


    public function generateData() {
        $this->isAuthorizedToAccess();

        try {
            $meili = new MeiliSearchService($this);
            $result = $meili->generateDataMeiliSearch();
            return new SimpleResponse($result);
        }
        catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    public function setup() {
        $this->isAuthorizedToAccess();

        $meili = new MeiliSearchService($this);
        $result = $meili->setup();
        return new SimpleResponse($result);
    }

    public function checkStatus($id) {
        $this->isAuthorizedToAccess();
        $meili = new MeiliSearchService($this);
        $result = $meili->checkStatus($id);
        return new SimpleResponse($result);
    }

    public function checkAllStatus() {
        $this->isAuthorizedToAccess();
        $meili = new MeiliSearchService($this);
        $result = $meili->checkAllStatus();
        return new SimpleResponse($result);
    }

    public function deleteAll() {
        $this->isAuthorizedToAccess();
        $meili = new MeiliSearchService($this);

        $res = $meili->deleteAllDocument();

        return new SimpleResponse($res);
    }

    public function client() {
        $this->isAuthorizedToAccess();
        $meili = new MeiliSearchService($this);

        $res = $meili->client();

        return new SimpleResponse($res->version());
    }

    public function index() {
        $this->isAuthorizedToAccess();
        $meili = new MeiliSearchService($this);

        $res = $meili->index();

        return new SimpleResponse($res->fetchRawInfo());
    }

    public function getIndex() {
        $this->isAuthorizedToAccess();
        $meili = new MeiliSearchService($this);

        $res = $meili->getIndex();

        return new SimpleResponse($res->fetchRawInfo());
    }

    public function getAllIndex() {
        $this->isAuthorizedToAccess();

        $meili = new MeiliSearchService($this);

        $res = $meili->getAllIndex();

        return new SimpleResponse($res);
    }

    public function getEnv() {
        $this->isAuthorizedToAccess();

        $res = [
            "active" => getenv("MEILI_SEARCH_ACTIVE"),
            "base_url" => getenv("MEILI_SEARCH_BASE_URL"),
            "master_key" => getenv("MEILI_SEARCH_MASTER_KEY"),
            "access_pass" => getenv("MEILI_SEARCH_API_ACCESS_PASS"),
        ];

        return new SimpleResponse($res);
    }

    public function getRecord() {
        $this->isAuthorizedToAccess();

        $res = MeilisearchRecord::find([
            'order' => 'id ASC'
        ]);

        return new SimpleResponse($res);
    }


    private function isAuthorizedToAccess() {
        $this->checkScopes(['admin.view']);
        if(!$this->request->hasHeader("Access-Key")) throw new CustomErrorException(401, "You're not allowed to access!");
        if($this->request->getHeader("Access-Key") != getenv('MEILI_SEARCH_API_ACCESS_PASS')) throw new CustomErrorException(401, "You're not allowed to access!");
    }
}
