#pragma once

#include <yandex/maps/wiki/social/common.h>
#include <yandex/maps/wiki/social/feedback/consts.h>
#include <yandex/maps/wiki/social/feedback/enums.h>
#include <yandex/maps/wiki/social/feedback/task.h>

#include <maps/libs/chrono/include/time_point.h>
#include <optional>

namespace maps::wiki::social::feedback {

class TaskPatch
{
public:
    explicit TaskPatch(TUid updater) : updater_(updater) {}

    TaskPatch& setAcquired();
    TaskPatch& setReleased();
    TaskPatch& setAcquired(const chrono::TimePoint& date);  // for testing purposes
    TaskPatch& setResolution(std::optional<Resolution> Resolution);
    TaskPatch& setDeployedAt(chrono::TimePoint);  // undeploy not available
    TaskPatch& setHidden(bool);
    TaskPatch& setBucket(Bucket);
    TaskPatch& setNeedInfo(std::optional<std::string> requestTemplate);
    TaskPatch& setDuplicateHeadId(std::optional<TId>);
    TaskPatch& setViewedByUpdater();
    TaskPatch& setCommentId(TId);
    TaskPatch& setType(Type);
    TaskPatch& setPosition(geolib3::Point2);
    TaskPatch& setProcessingLvl(ProcessingLvl, std::optional<Verdict> suggestedVerdict = std::nullopt);

    TUid updater() const { return updater_; }
    const std::optional<bool>& isAcquired() const { return isAcquired_; }
    const std::optional<chrono::TimePoint>& acquiredAt() const { return acquiredAt_; }
    const std::optional<std::optional<Resolution>>& resolution() const { return resolution_; }
    const std::optional<chrono::TimePoint>& deployedAt() const { return deployedAt_; }
    const std::optional<bool>& hidden() const { return hidden_; }
    const std::optional<Bucket>& bucket() const { return bucket_; }
    const std::optional<std::string>& needInfoRequestTemplate() const { return needInfoRequestTemplate_; }
    const std::optional<std::optional<TId>>& duplicateHeadId() const { return duplicateHeadId_; }
    bool viewedByUpdater() const { return viewedByUpdater_; }
    std::optional<Verdict> suggestedVerdict() const { return suggestedVerdict_; }
    const std::optional<TId>& commentId() const { return commentId_; }
    const std::optional<Type>& type() const { return type_; }
    const std::optional<ProcessingLvl>& processingLvl() const { return processingLvl_; }
    const std::optional<geolib3::Point2>& position() const { return position_; }

private:
    TUid updater_;
    std::optional<bool> isAcquired_;
    std::optional<chrono::TimePoint> acquiredAt_;
    std::optional<std::optional<Resolution>> resolution_;
    std::optional<chrono::TimePoint> deployedAt_;
    std::optional<bool> hidden_;
    std::optional<Bucket> bucket_;
    std::optional<std::string> needInfoRequestTemplate_;
    std::optional<std::optional<TId>> duplicateHeadId_;
    bool viewedByUpdater_ = false;
    std::optional<ProcessingLvl> processingLvl_;
    std::optional<Verdict> suggestedVerdict_;
    std::optional<TId> commentId_;
    std::optional<Type> type_;
    std::optional<geolib3::Point2> position_;
};

} // namespace maps::wiki::social::feedback
