#include "description.h"
#include <yandex/maps/wiki/common/string_utils.h>

#include <iomanip>
#include <sstream>

namespace maps::wiki::socialsrv {

namespace {

const std::string STATIC_API_PREFIX = "https://static-maps.yandex.ru/1.x/";

const int COLOR_NUM = 5;

std::array<std::string, COLOR_NUM> colors {
    "0c923b", "0c4492", "920c71", "920c13", "fbc56f"
};

} // namespace anonymous

std::string constructRouteGapDescrLink(
    const geolib3::BoundingBox& bbox,
    const geolib3::PointsVector& points,
    const std::vector<geolib3::Polyline2>& polylines)
{
    std::string link = STATIC_API_PREFIX + "?l=map";

    link += "&bbox=";

    link += std::to_string(bbox.minX()) + "," + std::to_string(bbox.minY()) + "~";
    link += std::to_string(bbox.maxX()) + "," + std::to_string(bbox.maxY());

    link += "&pt=";

    REQUIRE(points.size() == 2, "Number of points should be equal to 2");
    const auto& first = points[0];
    const auto& second = points[1];
    link += std::to_string(first.x()) + "," + std::to_string(first.y()) + ",pm2am~";
    link += std::to_string(second.x()) + "," + std::to_string(second.y()) + ",pm2bm";

    link += "&pl=";

    REQUIRE(polylines.size() <= COLOR_NUM,
        "Number of polylines should not be greater than " + std::to_string(COLOR_NUM));

    int curColor = 0;
    std::vector<std::pair<std::string, geolib3::Polyline2>> coloredPolylines;
    for (const auto& polyline : polylines) {
        if (polyline.pointsNumber() != 0) {
            REQUIRE(polyline.pointsNumber() >= 2,
                "Number of points in polyline should be at least 2");
            coloredPolylines.emplace_back(colors[curColor], polyline);
            curColor++;
        }
    }

    link += common::join(
        coloredPolylines.begin(),
        coloredPolylines.end(),
        [] (const auto& coloredPolyline) {
            const auto& [color, polyline] = coloredPolyline;

            auto colorWidth = "c:" + color + "C0,w:3";

            auto polylineStr = common::join(
                polyline.points().begin(),
                polyline.points().end(),
                [] (const auto& point) {
                    return std::to_string(point.x()) + "," +
                           std::to_string(point.y());
                },
                ","
            );

            return std::move(colorWidth) + "," + std::move(polylineStr);
        },
        "~"
    );

    link += "&size=650,450";

    return link;
}

std::string constructProhibitedPathDescrLink(const geolib3::Polyline2& geoPath)
{
    ASSERT(!geoPath.points().empty());

    std::stringstream url;

    url << STATIC_API_PREFIX << "?l=map&pl=c:cc0000,w:3";
    url << std::fixed << std::setprecision(8);

    for (const auto& point: geoPath.points()) {
        url << "," << point.x() << "," << point.y();
    }

    const auto& start = geoPath.points().front();
    const auto& end = geoPath.points().back();

    url << "&pt=" << start.x() << ","<< start.y() << ",ya_ru"
        << "~" << end.x() << ","<< end.y() << ",flag";

    return url.str();
}

} // namespace maps::wiki::socialsrv
