<?php

/**
* Copyright Maarch since 2008 under licence GPLv3.
* See LICENCE.txt file at the root folder for more details.
* This file is part of Maarch software.
*
*/

/**
* @brief Auto Complete Controller
* @author dev@maarch.org
*/

namespace SrcCore\controllers;

use Contact\controllers\ContactController;
use Contact\controllers\ContactGroupController;
use Contact\models\ContactModel;
use Entity\models\EntityModel;
use Respect\Validation\Validator;
use Slim\Http\Request;
use Slim\Http\Response;
use SrcCore\models\CoreConfigModel;
use SrcCore\models\CurlModel;
use SrcCore\models\DatabaseModel;
use SrcCore\models\TextFormatModel;
use SrcCore\models\ValidatorModel;
use Status\models\StatusModel;
use Tag\models\TagModel;
use User\models\UserModel;
use Folder\models\FolderModel;
use Folder\controllers\FolderController;

class AutoCompleteController
{
    const LIMIT = 50;
    const TINY_LIMIT = 5;

    public static function getContacts(Request $request, Response $response)
    {
        $data = $request->getQueryParams();

        $check = Validator::stringType()->notEmpty()->validate($data['search']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
        }

        $searchItems = explode(' ', $data['search']);

        $fields = '(contact_firstname ilike ? OR contact_lastname ilike ? OR firstname ilike ? OR lastname ilike ? OR society ilike ? 
                    OR address_num ilike ? OR address_street ilike ? OR address_town ilike ? OR address_postal_code ilike ?)';
        $where = [];
        $requestData = [];
        foreach ($searchItems as $item) {
            if (strlen($item) >= 2) {
                $where[] = $fields;
                for ($i = 0; $i < 9; $i++) {
                    $requestData[] = "%{$item}%";
                }
            }
        }

        $contacts = ContactModel::getOnView([
            'select'    => ['*'],
            'where'     => $where,
            'data'      => $requestData,
            'limit'     => self::TINY_LIMIT
        ]);

        $color = (!empty($data['color']) && $data['color'] == 'true');
        $autocompleteData = [];
        foreach ($contacts as $contact) {
            $autocompleteData[] = AutoCompleteController::getFormattedContact(['contact' => $contact, 'color' => $color])['contact'];
        }

        return $response->withJson($autocompleteData);
    }

    public static function getUsers(Request $request, Response $response)
    {
        $data = $request->getQueryParams();
        $check = Validator::stringType()->notEmpty()->validate($data['search']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
        }

        $excludedUsers = ['superadmin'];

        $requestData = AutoCompleteController::getDataForRequest([
            'search'        => $data['search'],
            'fields'        => '(firstname ilike ? OR lastname ilike ?)',
            'where'         => ['status not in (?)', 'user_id not in (?)'],
            'data'          => [['DEL', 'SPD'], $excludedUsers],
            'fieldsNumber'  => 2,
        ]);

        $users = UserModel::get([
            'select'    => ['id', 'user_id', 'firstname', 'lastname'],
            'where'     => $requestData['where'],
            'data'      => $requestData['data'],
            'orderBy'   => ['lastname'],
            'limit'     => self::LIMIT
        ]);

        $data = [];
        foreach ($users as $value) {
            $primaryEntity = UserModel::getPrimaryEntityByUserId(['userId' => $value['user_id']]);
            $data[] = [
                'type'                  => 'user',
                'id'                    => $value['user_id'],
                'serialId'              => $value['id'],
                'idToDisplay'           => "{$value['firstname']} {$value['lastname']}",
                'descriptionToDisplay'  => empty($primaryEntity) ? '' : $primaryEntity['entity_label'],
                'otherInfo'             => ''
            ];
        }

        return $response->withJson($data);
    }

    public static function getMaarchParapheurUsers(Request $request, Response $response)
    {
        $data = $request->getQueryParams();
        $check = Validator::stringType()->notEmpty()->validate($data['search']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'search is empty']);
        }

        if (!empty($data['exludeAlreadyConnected'])) {
            $usersAlreadyConnected = UserModel::get([
                'select' => ['external_id->>\'maarchParapheur\' as external_id'],
                'where' => ['external_id->>\'maarchParapheur\' is not null']
            ]);
            $excludedUsers = array_column($usersAlreadyConnected, 'external_id');
        }

        $loadedXml = CoreConfigModel::getXmlLoaded(['path' => 'modules/visa/xml/remoteSignatoryBooks.xml']);

        if ($loadedXml->signatoryBookEnabled == 'maarchParapheur') {
            foreach ($loadedXml->signatoryBook as $value) {
                if ($value->id == "maarchParapheur") {
                    $url      = $value->url;
                    $userId   = $value->userId;
                    $password = $value->password;
                    break;
                }
            }

            $curlResponse = CurlModel::execSimple([
                'url'           => rtrim($url, '/') . '/rest/autocomplete/users?search='.urlencode($data['search']),
                'basicAuth'     => ['user' => $userId, 'password' => $password],
                'headers'       => ['content-type:application/json'],
                'method'        => 'GET'
            ]);

            if ($curlResponse['code'] != '200') {
                if (!empty($curlResponse['response']['errors'])) {
                    $errors =  $curlResponse['response']['errors'];
                } else {
                    $errors =  $curlResponse['errors'];
                }
                if (empty($errors)) {
                    $errors = 'An error occured. Please check your configuration file.';
                }
                return $response->withStatus(400)->withJson(['errors' => $errors]);
            }

            foreach ($curlResponse['response'] as $key => $value) {
                if (!empty($data['exludeAlreadyConnected']) && in_array($value['id'], $excludedUsers)) {
                    unset($curlResponse['response'][$key]);
                    continue;
                }
                $curlResponse['response'][$key]['idToDisplay'] = $value['firstname'] . ' ' . $value['lastname'];
                $curlResponse['response'][$key]['externalId']['maarchParapheur'] = $value['id'];
            }
            return $response->withJson($curlResponse['response']);
        } else {
            return $response->withStatus(403)->withJson(['errors' => 'maarchParapheur is not enabled']);
        }
    }

    public static function getContactsAndUsers(Request $request, Response $response)
    {
        $data = $request->getQueryParams();

        $check = Validator::stringType()->notEmpty()->validate($data['search']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
        }

        $searchItems = explode(' ', $data['search']);

        $fields = '(contact_firstname ilike ? OR contact_lastname ilike ? OR firstname ilike ? OR lastname ilike ? OR society ilike ? 
                    OR address_num ilike ? OR address_street ilike ? OR address_town ilike ? OR address_postal_code ilike ?)';
        $where = [];
        $requestData = [];
        foreach ($searchItems as $item) {
            if (strlen($item) >= 2) {
                $where[] = $fields;
                for ($i = 0; $i < 9; $i++) {
                    $requestData[] = "%{$item}%";
                }
            }
        }

        $contacts = ContactModel::getOnView([
            'select'    => ['*'],
            'where'     => $where,
            'data'      => $requestData,
            'limit'     => self::TINY_LIMIT
        ]);

        $color = (!empty($data['color']) && $data['color'] == 'true');

        $onlyContacts = [];
        $autocompleteData = [];
        foreach ($contacts as $contact) {
            if (!empty($data['onlyContacts']) && $data['onlyContacts'] == 'true' && !in_array($contact['contact_id'], $onlyContacts)) {
                $autocompleteData[] = AutoCompleteController::getFormattedOnlyContact(['contact' => $contact])['contact'];
                $onlyContacts[] = $contact['contact_id'];
            }
            $autocompleteData[] = AutoCompleteController::getFormattedContact(['contact' => $contact, 'color' => $color])['contact'];
        }

        $excludedUsers = ['superadmin'];

        $requestData = AutoCompleteController::getDataForRequest([
            'search'        => $data['search'],
            'fields'        => '(firstname ilike ? OR lastname ilike ?)',
            'where'         => ['status not in (?)', 'user_id not in (?)'],
            'data'          => [['DEL', 'SPD'], $excludedUsers],
            'fieldsNumber'  => 2,
        ]);

        $users = UserModel::get([
            'select'    => ['id', 'user_id', 'firstname', 'lastname'],
            'where'     => $requestData['where'],
            'data'      => $requestData['data'],
            'orderBy'   => ['lastname'],
            'limit'     => self::TINY_LIMIT
        ]);

        foreach ($users as $value) {
            $autocompleteData[] = [
                'type'          => 'user',
                'id'            => $value['id'],
                'idToDisplay'   => "{$value['firstname']} {$value['lastname']}",
                'otherInfo'     => "{$value['firstname']} {$value['lastname']}"
            ];
        }

        return $response->withJson($autocompleteData);
    }

    public static function getUsersForAdministration(Request $request, Response $response)
    {
        $data = $request->getQueryParams();
        $check = Validator::stringType()->notEmpty()->validate($data['search']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
        }

        $excludedUsers = ['superadmin'];

        if ($GLOBALS['userId'] != 'superadmin') {
            $entities = EntityModel::getAllEntitiesByUserId(['userId' => $GLOBALS['userId']]);

            $requestData = AutoCompleteController::getDataForRequest([
                'search'        => $data['search'],
                'fields'        => '(users.firstname ilike ? OR users.lastname ilike ?)',
                'where'         => [
                    'users.user_id = users_entities.user_id',
                    'users_entities.entity_id in (?)',
                    'users.status not in (?)'
                ],
                'data'          => [$entities, ['DEL', 'SPD']],
                'fieldsNumber'  => 2,
            ]);

            $users = DatabaseModel::select([
                'select'    => ['DISTINCT users.user_id', 'users.id', 'users.firstname', 'users.lastname'],
                'table'     => ['users, users_entities'],
                'where'     => $requestData['where'],
                'data'      => $requestData['data'],
                'limit'     => self::LIMIT
            ]);

            if (count($users) < self::LIMIT) {
                $requestData = AutoCompleteController::getDataForRequest([
                    'search'        => $data['search'],
                    'fields'        => '(users.firstname ilike ? OR users.lastname ilike ?)',
                    'where'         => [
                        'users_entities IS NULL',
                        'users.user_id not in (?)',
                        'users.status not in (?)'
                    ],
                    'data'          => [$excludedUsers, ['DEL', 'SPD']],
                    'fieldsNumber'  => 2,
                ]);

                $usersNoEntities = DatabaseModel::select([
                    'select'    => ['users.id', 'users.user_id', 'users.firstname', 'users.lastname'],
                    'table'     => ['users', 'users_entities'],
                    'left_join' => ['users.user_id = users_entities.user_id'],
                    'where'     => $requestData['where'],
                    'data'      => $requestData['data'],
                    'limit'     => (self::LIMIT - count($users))
                ]);

                $users = array_merge($users, $usersNoEntities);
            }
        } else {
            $requestData = AutoCompleteController::getDataForRequest([
                'search'        => $data['search'],
                'fields'        => '(firstname ilike ? OR lastname ilike ?)',
                'where'         => ['status not in (?)', 'user_id not in (?)'],
                'data'          => [['DEL', 'SPD'], $excludedUsers],
                'fieldsNumber'  => 2,
            ]);

            $users = UserModel::get([
                'select'    => ['id', 'user_id', 'firstname', 'lastname'],
                'where'     => $requestData['where'],
                'data'      => $requestData['data'],
                'orderBy'   => ['lastname'],
                'limit'     => self::LIMIT
            ]);
        }

        $data = [];
        foreach ($users as $value) {
            $data[] = [
                'type'          => 'user',
                'id'            => $value['id'],
                'idToDisplay'   => "{$value['firstname']} {$value['lastname']}",
                'otherInfo'     => $value['user_id']
            ];
        }

        return $response->withJson($data);
    }

    public static function getUsersForVisa(Request $request, Response $response)
    {
        $data = $request->getQueryParams();
        $check = Validator::stringType()->notEmpty()->validate($data['search']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
        }

        $excludedUsers = ['superadmin'];

        $requestData = AutoCompleteController::getDataForRequest([
            'search'        => $data['search'],
            'fields'        => '(users.firstname ilike ? OR users.lastname ilike ?)',
            'where'         => [
                'usergroup_content.group_id = usergroups_services.group_id',
                'usergroup_content.user_id = users.user_id',
                'usergroups_services.service_id in (?)',
                'users.user_id not in (?)',
                'users.status not in (?)'
            ],
            'data'          => [['visa_documents', 'sign_document'], $excludedUsers, ['DEL', 'SPD']],
            'fieldsNumber'  => 2,
        ]);

        $users = DatabaseModel::select([
            'select'    => ['DISTINCT users.user_id', 'users.firstname', 'users.lastname'],
            'table'     => ['users, usergroup_content, usergroups_services'],
            'where'     => $requestData['where'],
            'data'      => $requestData['data'],
            'order_by'  => ['users.lastname'],
            'limit'     => self::LIMIT
        ]);

        $data = [];
        foreach ($users as $value) {
            $data[] = [
                'type'          => 'user',
                'id'            => $value['user_id'],
                'idToDisplay'   => "{$value['firstname']} {$value['lastname']}",
                'otherInfo'     => ''
            ];
        }

        return $response->withJson($data);
    }

    public static function getEntities(Request $request, Response $response)
    {
        $data = $request->getQueryParams();
        $check = Validator::stringType()->notEmpty()->validate($data['search']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
        }

        $requestData = AutoCompleteController::getDataForRequest([
            'search'        => $data['search'],
            'fields'        => '(entity_label ilike ?)',
            'where'         => ['enabled = ?'],
            'data'          => ['Y'],
            'fieldsNumber'  => 1,
        ]);

        $entities = EntityModel::get([
            'select'    => ['id', 'entity_id', 'entity_label', 'short_label'],
            'where'     => $requestData['where'],
            'data'      => $requestData['data'],
            'orderBy'   => ['entity_label'],
            'limit'     => self::LIMIT
        ]);

        $data = [];
        foreach ($entities as $value) {
            $data[] = [
                'type'          => 'entity',
                'id'            => $value['entity_id'],
                'serialId'      => $value['id'],
                'idToDisplay'   => $value['entity_label'],
                'otherInfo'     => $value['short_label']
            ];
        }

        return $response->withJson($data);
    }

    public static function getStatuses(Request $request, Response $response)
    {
        $statuses = StatusModel::get(['select' => ['id', 'label_status', 'img_filename']]);

        $data = [];
        foreach ($statuses as $value) {
            $data[] = [
                'type'          => 'status',
                'id'            => $value['id'],
                'idToDisplay'   => $value['label_status'],
                'otherInfo'     => $value['img_filename']
            ];
        }

        return $response->withJson($data);
    }

    public static function getContactsForGroups(Request $request, Response $response)
    {
        $data = $request->getQueryParams();

        $check = Validator::stringType()->notEmpty()->validate($data['search']);
        $check = $check && Validator::stringType()->notEmpty()->validate($data['type']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
        }

        $searchItems = explode(' ', $data['search']);

        $fields = '(contact_firstname ilike ? OR contact_lastname ilike ? OR firstname ilike ? OR lastname ilike ? OR society ilike ? 
                    OR address_num ilike ? OR address_street ilike ? OR address_town ilike ? OR address_postal_code ilike ?)';
        $where = [];
        $requestData = [];
        if ($data['type'] != 'all') {
            $where = ['contact_type = ?'];
            $requestData = [$data['type']];
        }
        foreach ($searchItems as $item) {
            if (strlen($item) >= 2) {
                $where[] = $fields;
                for ($i = 0; $i < 9; $i++) {
                    $requestData[] = "%{$item}%";
                }
            }
        }

        $contacts = ContactModel::getOnView([
            'select'    => [
                'ca_id', 'firstname', 'lastname', 'contact_lastname', 'contact_firstname', 'society', 'address_num',
                'address_street', 'address_town', 'address_postal_code', 'is_corporate_person'
            ],
            'where'     => $where,
            'data'      => $requestData,
            'limit'     => 1000
        ]);

        $data = [];
        foreach ($contacts as $contact) {
            $data[] = ContactGroupController::getFormattedContact(['contact' => $contact])['contact'];
        }

        return $response->withJson($data);
    }

    public static function getBanAddresses(Request $request, Response $response)
    {
        $data = $request->getQueryParams();

        $check = Validator::stringType()->notEmpty()->validate($data['address']);
        $check = $check && Validator::stringType()->notEmpty()->validate($data['department']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
        }
        $customId = CoreConfigModel::getCustomId();

        if (is_dir("custom/{$customId}/referential/ban/indexes/{$data['department']}")) {
            $path = "custom/{$customId}/referential/ban/indexes/{$data['department']}";
        } elseif (is_dir('referential/ban/indexes/' . $data['department'])) {
            $path = 'referential/ban/indexes/' . $data['department'];
        } else {
            return $response->withStatus(400)->withJson(['errors' => 'Department indexes do not exist']);
        }

        \Zend_Search_Lucene_Analysis_Analyzer::setDefault(new \Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive());
        \Zend_Search_Lucene_Search_QueryParser::setDefaultOperator(\Zend_Search_Lucene_Search_QueryParser::B_AND);
        \Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding('utf-8');

        $index = \Zend_Search_Lucene::open($path);
        \Zend_Search_Lucene::setResultSetLimit(100);

        $data['address'] = str_replace(['*', '~', '-', '\''], ' ', $data['address']);
        $aAddress = explode(' ', $data['address']);
        foreach ($aAddress as $key => $value) {
            if (strlen($value) <= 2 && !is_numeric($value)) {
                unset($aAddress[$key]);
                continue;
            }
            if (strlen($value) >= 3 && $value != 'rue' && $value != 'avenue' && $value != 'boulevard') {
                $aAddress[$key] .= '*';
            }
        }
        $data['address'] = implode(' ', $aAddress);
        if (empty($data['address'])) {
            return $response->withJson([]);
        }

        $hits = $index->find(TextFormatModel::normalize(['string' => $data['address']]));

        $addresses = [];
        foreach ($hits as $key => $hit) {
            $addresses[] = [
                'banId'         => $hit->banId,
                'number'        => $hit->streetNumber,
                'afnorName'     => $hit->afnorName,
                'postalCode'    => $hit->postalCode,
                'city'          => $hit->city,
                'address'       => "{$hit->streetNumber} {$hit->afnorName}, {$hit->city} ({$hit->postalCode})"
            ];
        }

        return $response->withJson($addresses);
    }

    private static function getDataForRequest(array $aArgs)
    {
        ValidatorModel::notEmpty($aArgs, ['search', 'fields', 'where', 'data', 'fieldsNumber']);
        ValidatorModel::stringType($aArgs, ['search', 'fields']);
        ValidatorModel::arrayType($aArgs, ['where', 'data']);
        ValidatorModel::intType($aArgs, ['fieldsNumber']);

        $searchItems = explode(' ', $aArgs['search']);

        foreach ($searchItems as $item) {
            if (strlen($item) >= 2) {
                $aArgs['where'][] = $aArgs['fields'];
                for ($i = 0; $i < $aArgs['fieldsNumber']; $i++) {
                    $aArgs['data'][] = "%{$item}%";
                }
            }
        }

        return ['where' => $aArgs['where'], 'data' => $aArgs['data']];
    }

    public static function getFormattedContact(array $aArgs)
    {
        ValidatorModel::notEmpty($aArgs, ['contact']);
        ValidatorModel::arrayType($aArgs, ['contact']);
        ValidatorModel::boolType($aArgs, ['color']);

        if (!empty($aArgs['color'])) {
            $rate = ContactController::getFillingRate(['contact' => $aArgs['contact']]);
        }
        $rateColor = empty($rate['color']) ? '' : $rate['color'];

        $address = '';
        if ($aArgs['contact']['is_corporate_person'] == 'Y') {
            $address.= $aArgs['contact']['firstname'];
            $address.= (empty($address) ? $aArgs['contact']['lastname'] : " {$aArgs['contact']['lastname']}");
            $address .= ', ';
            if (!empty($aArgs['contact']['address_num'])) {
                $address.= $aArgs['contact']['address_num'] . ' ';
            }
            if (!empty($aArgs['contact']['address_street'])) {
                $address.= $aArgs['contact']['address_street'] . ' ';
            }
            if (!empty($aArgs['contact']['address_postal_code'])) {
                $address.= $aArgs['contact']['address_postal_code'] . ' ';
            }
            if (!empty($aArgs['contact']['address_town'])) {
                $address.= $aArgs['contact']['address_town'] . ' ';
            }
            if (!empty($aArgs['contact']['address_country'])) {
                $address.= $aArgs['contact']['address_country'];
            }
            $address = rtrim($address, ', ');
            $otherInfo = empty($address) ? "{$aArgs['contact']['society']}" : "{$aArgs['contact']['society']} - {$address}";
            $contact = [
                'type'          => 'contact',
                'id'            => $aArgs['contact']['ca_id'],
                'contact'       => $aArgs['contact']['society'],
                'address'       => $address,
                'idToDisplay'   => "{$aArgs['contact']['society']}<br/>{$address}",
                'otherInfo'     => $otherInfo,
                'rateColor'     => $rateColor
            ];
        } else {
            if (!empty($aArgs['contact']['address_num'])) {
                $address.= $aArgs['contact']['address_num'] . ' ';
            }
            if (!empty($aArgs['contact']['address_street'])) {
                $address.= $aArgs['contact']['address_street'] . ' ';
            }
            if (!empty($aArgs['contact']['address_postal_code'])) {
                $address.= $aArgs['contact']['address_postal_code'] . ' ';
            }
            if (!empty($aArgs['contact']['address_town'])) {
                $address.= $aArgs['contact']['address_town'] . ' ';
            }
            if (!empty($aArgs['contact']['address_country'])) {
                $address.= $aArgs['contact']['address_country'];
            }
            $contactToDisplay = "{$aArgs['contact']['contact_firstname']} {$aArgs['contact']['contact_lastname']}";
            if (!empty($aArgs['contact']['society'])) {
                $contactToDisplay .= " ({$aArgs['contact']['society']})";
            }

            $otherInfo = empty($address) ? "{$contactToDisplay}" : "{$contactToDisplay} - {$address}";
            $contact = [
                'type'          => 'contact',
                'id'            => $aArgs['contact']['ca_id'],
                'contact'       => $contactToDisplay,
                'address'       => $address,
                'idToDisplay'   => "{$contactToDisplay}<br/>{$address}",
                'otherInfo'     => $otherInfo,
                'rateColor'     => $rateColor
            ];
        }

        return ['contact' => $contact];
    }

    public static function getFormattedOnlyContact(array $aArgs)
    {
        ValidatorModel::notEmpty($aArgs, ['contact']);
        ValidatorModel::arrayType($aArgs, ['contact']);

        if ($aArgs['contact']['is_corporate_person'] == 'Y') {
            $contact = [
                'type'          => 'onlyContact',
                'id'            => $aArgs['contact']['contact_id'],
                'idToDisplay'   => $aArgs['contact']['society'],
                'otherInfo'     => $aArgs['contact']['society'],
                'rateColor'     => ''
            ];
        } else {
            $contactToDisplay = "{$aArgs['contact']['contact_firstname']} {$aArgs['contact']['contact_lastname']}";
            if (!empty($aArgs['contact']['society'])) {
                $contactToDisplay .= " ({$aArgs['contact']['society']})";
            }
            $contact = [
                'type'          => 'onlyContact',
                'id'            => $aArgs['contact']['contact_id'],
                'idToDisplay'   => $contactToDisplay,
                'otherInfo'     => $contactToDisplay,
                'rateColor'     => ''
            ];
        }

        return ['contact' => $contact];
    }

    public static function getFolders(Request $request, Response $response)
    {
        $data = $request->getQueryParams();

        $check = Validator::stringType()->notEmpty()->validate($data['search']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
        }

        $scopedFolders = FolderController::getScopeFolders(['login' => $GLOBALS['userId']]);

        $arrScopedFoldersIds = array_column($scopedFolders, 'id');

        $selectedFolders = FolderModel::get([
            'where'    => ['label ilike ? AND id IN(?)'],
            'data'     => [ '%'.$data['search'].'%', $arrScopedFoldersIds],
            'orderBy'  => ['label']
        ]);

        $getFomatedFolders = function ($value) {
            return $return = [
                'id' => $value['id'],
                'idToDisplay' => $value['label'],
                'otherInfo' => ''
            ];
        };
        return $response->withJson(array_map($getFomatedFolders, $selectedFolders));
    }

    public static function getTags(Request $request, Response $response)
    {
        $data = $request->getQueryParams();
        $check = Validator::stringType()->notEmpty()->validate($data['search']);
        if (!$check) {
            return $response->withStatus(400)->withJson(['errors' => 'Bad Request']);
        }

        $requestData = AutoCompleteController::getDataForRequest([
            'search'        => $data['search'],
            'fields'        => '(tag_label ilike ?)',
            'where'         => ['1 = ?'],
            'data'          => ['1'],
            'fieldsNumber'  => 1,
        ]);

        $tags = TagModel::get([
            'select'    => ['tag_id', 'tag_label'],
            'where'     => $requestData['where'],
            'data'      => $requestData['data'],
            'orderBy'   => ['tag_label'],
            'limit'     => self::LIMIT
        ]);

        $data = [];
        foreach ($tags as $value) {
            $data[] = [
                'id'            => $value['tag_id'],
                'idToDisplay'   => $value['tag_label']
            ];
        }

        return $response->withJson($data);
    }
}