#pragma once

#include <yandex/maps/wiki/social/common.h>
#include <yandex/maps/wiki/social/event.h>
#include <yandex/maps/wiki/social/moderation.h>

#include <maps/libs/common/include/exception.h>

#include <pqxx/pqxx>
#include <vector>
#include <memory>

namespace maps::wiki::social {

class Factory;

using TaskIds = TIds;

class Resolved
{
public:
    TUid uid() const { return uid_; }
    const std::string& date() const { return date_; }
    ResolveResolution resolution() const { return resolution_; }

private:
    friend class Factory;
    explicit Resolved(const pqxx::row& row);

    TUid uid_;
    std::string date_;
    ResolveResolution resolution_;
};

struct Closed
{
    TUid uid() const { return uid_; }
    const std::string& date() const { return date_; }
    CloseResolution resolution() const { return resolution_; }

private:
    friend class Factory;
    explicit Closed(const pqxx::row& row);

    TUid uid_;
    std::string date_;
    CloseResolution resolution_;
};

struct Locked
{
    TUid uid() const { return uid_; }
    const std::string& date() const { return date_; }

private:
    friend class Factory;
    explicit Locked(const pqxx::row& row);

    TUid uid_;
    std::string date_;
};

class Task
{
public:
    TId id() const { return eventId_; }
    TId commitId() const { return commitId_; }

    const Event& event() const { return event_; }

    bool isResolved() const { return resolved_.uid() != 0; }
    const Resolved& resolved() const { ASSERT(isResolved()); return resolved_; }

    bool isClosed() const { return closed_.uid() != 0; }
    const Closed& closed() const { ASSERT(isClosed()); return closed_; }

    bool isLocked() const { return locked_.uid() != 0; }
    const Locked& locked() const { ASSERT(isLocked()); return locked_; }
    void setLocked(Locked newLocked) { locked_ = std::move(newLocked); }

private:
    friend class Factory;

    Task(const pqxx::row& row, Event event);

    TId eventId_;
    TId commitId_;
    Event event_;
    Resolved resolved_;
    Closed closed_;
    Locked locked_;
};

using Tasks = std::vector<Task>;

} // namespace maps::wiki::social
