#pragma once

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

#include <maps/libs/ymapsdf/include/rd.h>
#include <maps/libs/ymapsdf/include/ft.h>

#include <maps/libs/geolib/include/point.h>
#include <maps/libs/geolib/include/polyline.h>

#include <optional>
#include <string>
#include <vector>

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

class Description;

struct AbsentObjectDescr
{
    std::optional<std::string> correctName;

    Description toDescription() const;
};

struct AbsentRoadDescr
{
    std::optional<std::string> roadName;

    Description toDescription() const;
};

struct WrongRoadDirectionDescr
{
    ymapsdf::rd::Direction correctDirection;

    Description toDescription() const;
};

struct WrongSpeedLimitDescr
{
    std::optional<ymapsdf::rd::Direction> direction;
    bool truck;
    bool confirmingSignNotFound;
    std::optional<int> currentSpeedLimit;
    int correctSpeedLimit;

    Description toDescription() const;
};

struct AbsentEntranceDescr
{
    std::optional<std::string> entranceName;

    Description toDescription() const;
};

struct DeleteEntranceDescr
{
    std::optional<std::string> entranceName;

    Description toDescription() const;
};

struct EntranceWrongPositionDescr
{
    std::optional<std::string> entranceName;

    Description toDescription() const;
};

struct EntranceCorrectionDescr
{
    std::optional<std::string> entranceName;
    std::optional<std::string> correctName;

    Description toDescription() const;
};

struct SubwayCorrectionNameAndPositionDescr
{
    std::string correctName;

    Description toDescription() const;
};

struct SubwayCorrectionNameDescr
{
    std::string correctName;

    Description toDescription() const;
};

struct RemoveObjectDescr
{
    std::optional<std::string> name;

    Description toDescription() const;
};

struct WrongNameDescr
{
    std::optional<std::string> currentName;
    std::optional<std::string> correctName;

    Description toDescription() const;
};

struct WrongParkingTypeDescr
{
    ymapsdf::ft::Type currentParkingType;
    ymapsdf::ft::Type correctParkingType;

    Description toDescription() const;
};

struct AddressPositionCorrectionDescr
{
    geolib3::Point2 geoPosWrong;
    geolib3::Point2 geoPosCorrect;

    Description toDescription() const;
};

enum class AddressDescriptionType
{
    NewAddress,
    AddressCorrection,
};

struct AddressDescr
{
    AddressDescriptionType type;
    std::optional<std::string> correctStreet;
    std::optional<std::string> correctHouse;
    std::optional<std::string> correctAddressString;

    Description toDescription() const;
};

struct NoPublicTransportStopDescr
{
    std::optional<std::string> publicStopName;

    Description toDescription() const;
};

struct RouteGapDescr
{
    int tracksCount;
    double probability;
    double countTrackRips;
    std::string link;

    Description toDescription() const;
};

struct NoNeededParkingTypeDescr
{
    bool changeExistedObject = false;
    std::optional<bool> toll;
    Description toDescription() const;
};

struct MandatoryDirectionTrafficSignDescr
{
    static Description toDescription();
};

struct ProhibitedTurnSignDescr
{
    static Description toDescription();
};

struct OneWayTrafficSignDescr
{
    static Description toDescription();
};

struct TrafficLaneSignDescr
{
    static Description toDescription();
};

struct TrafficProhibitedSignDescr
{
    static Description toDescription();
};

struct TrafficCircleSignDescr
{
    static Description toDescription();
};

struct SuggestedActionDescr
{
    SuggestedAction action;
    Description toDescription() const;
};

struct ProhibitedPathDescr {
    std::optional<Movement> movement;
    std::string prohibitedPathUrl;
    bool prohibited;
    maps::ymapsdf::rd::AccessId accessId;

    Description toDescription() const;
};

struct AbsentAddressDescr {
    std::string number;

    Description toDescription() const;
};

struct AbsentTrafficLightDescr {
    static Description toDescription();
};

struct SpeedBumpSignDescr {
    bool ahead;
    Description toDescription() const;
};

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