#include "absl/flags/flag.h"
#include "absl/log/check.h"
#include "absl/log/log.h"

#include "aos/init.h"
#include "frc971/constants/constants_sender_lib.h"
#include "frc971/control_loops/drivetrain/localization/localizer_output_generated.h"
#include "frc971/vision/target_map_utils.h"
#include "frc971/vision/vision_generated.h"
#include "y2023/localizer/localizer.h"

ABSL_FLAG(std::string, config, "aos_config.json",
          "Path to the config file to use.");

ABSL_FLAG(uint64_t, min_april_id, 1,
          "Minimum april id to consider as part of the field and ignore");
ABSL_FLAG(uint64_t, max_april_id, 8,
          "Maximum april id to consider as part of the field and ignore");

// This binary allows us to place extra april tags on the field and verify
// that we can compute their field pose correctly

namespace y2023::vision {

using localizer::Localizer;

Localizer::Transform LocalizerOutputToTransform(
    const frc971::controls::LocalizerOutput &localizer) {
  const auto T_field_robot =
      Eigen::Translation3d(localizer.x(), localizer.y(), 0.0);

  Eigen::AngleAxisd robot_yaw_angle(localizer.theta(),
                                    Eigen::Vector3d::UnitZ());
  const auto R_field_robot = Eigen::Quaterniond(robot_yaw_angle);
  const Localizer::Transform H_field_robot =
      (T_field_robot * R_field_robot).matrix();
  return H_field_robot;
}

void HandleDetections(
    const frc971::vision::TargetMap &detections,
    const Localizer::Transform &H_robot_camera,
    aos::Fetcher<frc971::controls::LocalizerOutput> *localizer_fetcher) {
  localizer_fetcher->Fetch();
  CHECK(localizer_fetcher->get());

  for (const auto *target_pose : *detections.target_poses()) {
    // Only look at april tags not part of the field
    if (target_pose->id() >= absl::GetFlag(FLAGS_min_april_id) &&
        target_pose->id() <= absl::GetFlag(FLAGS_max_april_id)) {
      continue;
    }

    const Localizer::Transform H_camera_target =
        frc971::vision::PoseToTransform(target_pose);
    const Localizer::Transform H_field_robot =
        LocalizerOutputToTransform(*localizer_fetcher->get());

    // Get the field-based target pose using the detection, extrinsics, and
    // localizer output
    const Localizer::Transform H_field_target =
        H_field_robot * H_robot_camera * H_camera_target;

    LOG(INFO) << "Field to target " << target_pose->id();
    LOG(INFO) << "H_field_robot " << H_field_robot;
    LOG(INFO) << "H_robot_camera " << H_robot_camera;
    LOG(INFO) << "H_camera_target " << H_camera_target;
    LOG(INFO) << "Transform: " << H_field_target;
    LOG(INFO) << "Translation: "
              << Eigen::Affine3d(H_field_target).translation();
    LOG(INFO);
  }
}

void LocalizationVerifierMain() {
  aos::FlatbufferDetachedBuffer<aos::Configuration> config =
      aos::configuration::ReadConfig(absl::GetFlag(FLAGS_config));

  frc971::constants::WaitForConstants<Constants>(&config.message());

  aos::ShmEventLoop event_loop(&config.message());

  frc971::constants::ConstantsFetcher<Constants> constants_fetcher(&event_loop);

  aos::Fetcher<frc971::controls::LocalizerOutput> localizer_fetcher =
      event_loop.MakeFetcher<frc971::controls::LocalizerOutput>("/localizer");

  for (const auto *camera : *constants_fetcher.constants().cameras()) {
    CHECK(camera->has_calibration());
    Localizer::Transform H_robot_camera =
        frc971::control_loops::drivetrain::FlatbufferToTransformationMatrix(
            *camera->calibration()->fixed_extrinsics());

    const std::string_view pi_name =
        camera->calibration()->node_name()->string_view();
    event_loop.MakeWatcher(
        absl::StrCat("/", pi_name, "/camera"),
        [H_robot_camera,
         &localizer_fetcher](const frc971::vision::TargetMap &target_map) {
          HandleDetections(target_map, H_robot_camera, &localizer_fetcher);
        });
  }
  event_loop.Run();
}

}  // namespace y2023::vision

int main(int argc, char **argv) {
  aos::InitGoogle(&argc, &argv);
  y2023::vision::LocalizationVerifierMain();
}
