#pragma once

#include <maps/wikimap/mapspro/services/editor/src/common.h>
#include <maps/wikimap/mapspro/libs/controller/include/basecontroller.h>

#include <string>

namespace maps
{
namespace wiki
{
typedef std::vector<TOid> OidsVector;

class AttributesFilter;

class GetSuggest;
template<>
struct controller::ResultType<GetSuggest>
{
    struct SuggestedObject
    {
        TOid id;
        TCommitId commitId;
        std::string name;
        std::string path;
        std::string categoryId;
    };
    StringSet categories;
    std::vector<SuggestedObject> suggestedObjects;
};

class GetSuggest: public controller::BaseController<GetSuggest>
{
public:
    enum class GeomPredicate
    {
        Distance,
        Intersects
    };

    struct Request
    {
        std::string categories;
        std::string searchText;
        size_t limit;
        std::string ll;
        std::string token;
        TBranchId branchId;
        double distance;
        Geom geometry;
        GeomPredicate predicate;
        StringMap parsedAttributesAndValues;
        std::string lang;
    };

    explicit GetSuggest(const Request& request);
    virtual ~GetSuggest() {};
    virtual std::string printRequest() const;

protected:
    virtual void control();

private:
    void collectOidsWithinGeometryRequest(Transaction& work, const AttributesFilter& attributesFilter);
    void collectNoSuggestOwnGeometryObjectsOids(Transaction& work);
    void performSuggestSearch(Transaction& work, const AttributesFilter& attributesFilter);

    Request request_;
    OidsVector objectIdsWithSuggest_;
    OidsVector noSuggestOwnGeometryObjectsOids_;
    std::string geomWkb_;
    TOIds foundIds_;

};

std::ostream& operator << (std::ostream& os, GetSuggest::GeomPredicate predicate);
std::istream& operator >> (std::istream& is, GetSuggest::GeomPredicate& predicate);
}//wiki
}//maps
