#pragma once

#include <yandex/maps/wiki/filters/common.h>
#include <yandex/maps/wiki/filters/stored_expression.h>

#include <yandex/maps/wiki/common/before_after.h>
#include <yandex/maps/wiki/common/paged_result.h>

#include <boost/optional.hpp>
#include <pqxx/pqxx>

#include <string>
#include <list>
#include <memory>

namespace maps::wiki::filters {

class StoredFilter
{
public:
    struct ResultBeforeAfter
    {
        std::vector<StoredFilter> filters;
        bool hasMore = false;
    };

    explicit StoredFilter(const pqxx::row& row);
    StoredFilter(const pqxx::row& row, StoredExpression expression);
    ~StoredFilter();

    TFilterId id() const;
    const std::string& createdAt() const;
    TUId createdBy() const;

    bool isDeleted() const;
    void setDeleted(pqxx::transaction_base& txn);

    const std::string& name() const;
    void setName(pqxx::transaction_base& txn, const std::string& value);

    bool isPublic() const;
    void setPublic(pqxx::transaction_base& txn, bool value);

    const StoredExpression& expression() const;
    void setExpression(
            pqxx::transaction_base& txn, TUId uid, const std::string& expression);


    static StoredFilter create(
            pqxx::transaction_base& txn, TUId uid,
            const std::string& name, bool isPublic, const std::string& expression);

    static StoredFilter load(pqxx::transaction_base& txn, TFilterId id);

    static common::PagedResult<std::vector<StoredFilter>> loadPaged(
            pqxx::transaction_base& txn, TUId uid,
            size_t page, size_t perPage, boost::optional<TUId> createdBy);

    static ResultBeforeAfter load(
        pqxx::transaction_base& txn,
        TUId uid,
        boost::optional<TUId> createdBy,
        const std::string& namePart,
        TFilterId startID,
        common::BeforeAfter beforeAfter,
        size_t limit);
private:
    void initAttrs(const pqxx::row& row);

    TFilterId id_;
    std::string createdAt_;
    TUId createdBy_;
    bool isDeleted_;

    std::string name_;
    bool isPublic_;
    StoredExpression expression_;
};

} // namespace maps::wiki::filters
