#include <maps/wikimap/mapspro/services/mrc/libs/db/tests/eye/common.h>

#include <library/cpp/testing/gtest/gtest.h>
#include <maps/libs/chrono/include/time_point.h>
#include <maps/libs/common/include/exception.h>
#include <maps/wikimap/mapspro/services/mrc/libs/db/include/eye/verified_detection_location_gateway.h>
#include <yandex/maps/mrc/unittest/unittest_config.h>

namespace maps::mrc::db::eye::tests {

TEST_F(DetectionFixture, make_verified_detection_location)
{
    VerifiedDetectionLocation location(
        VerificationSource::Toloka,
        detections[0].id()
    );

    {
        auto txn = txnHandle();
        db::eye::VerifiedDetectionLocationGateway(*txn).insertx(location);
        txn->commit();
    }

    {
        auto txn = txnHandle();
        VerifiedDetectionLocation loadedLocation
            = db::eye::VerifiedDetectionLocationGateway(*txn).loadById(location.id());

        EXPECT_EQ(loadedLocation.id(), location.id());
        EXPECT_EQ(loadedLocation.detectionId(), detections[0].id());
        EXPECT_EQ(loadedLocation.mercatorPos(), std::nullopt);
        EXPECT_EQ(loadedLocation.geodeticPos(), std::nullopt);
        EXPECT_EQ(loadedLocation.rotation(), std::nullopt);
    }
}

TEST_F(DetectionFixture, unique_verified_detection_location)
{
    VerifiedDetectionLocation location1(
        VerificationSource::Toloka,
        detections[0].id()
    );

    {
        auto txn = txnHandle();
        db::eye::VerifiedDetectionLocationGateway(*txn).insertx(location1);
        txn->commit();
    }

    VerifiedDetectionLocation location2(
        VerificationSource::Toloka,
        detections[0].id()
    );

    {
        auto txn = txnHandle();
        EXPECT_THROW(
            db::eye::VerifiedDetectionLocationGateway(*txn).insertx(location2),
            maps::sql_chemistry::UniqueViolationError
        );
    }
}

TEST_F(DetectionFixture, set_position_verified_detection_location)
{
    VerifiedDetectionLocation location(
        VerificationSource::Toloka,
        detections[0].id()
    );

    location.setMercatorPos(geolib3::Point2(1, 2));

    {
        auto txn = txnHandle();
        db::eye::VerifiedDetectionLocationGateway(*txn).insertx(location);
        txn->commit();
    }

    {
        auto txn = txnHandle();
        VerifiedDetectionLocation loadedLocation
            = db::eye::VerifiedDetectionLocationGateway(*txn).loadById(location.id());

        EXPECT_EQ(loadedLocation.id(), location.id());
        EXPECT_EQ(loadedLocation.detectionId(), detections[0].id());
        EXPECT_DOUBLE_EQ(loadedLocation.mercatorPos().value().x(), 1.);
        EXPECT_DOUBLE_EQ(loadedLocation.mercatorPos().value().y(), 2.);
    }
}

} // namespace maps::mrc::db::eye::tests
