#include "Eigen/Dense"
#include "Eigen/Geometry"
#include "absl/strings/str_format.h"
#include <opencv2/core/eigen.hpp>

#include "aos/events/logging/log_reader.h"
#include "aos/events/logging/log_writer.h"
#include "aos/init.h"
#include "aos/network/team_number.h"
#include "aos/time/time.h"
#include "aos/util/file.h"
#include "frc971/constants/constants_sender_lib.h"
#include "frc971/control_loops/quaternion_utils.h"
#include "frc971/vision/extrinsics_calibration.h"
#include "frc971/vision/vision_generated.h"
#include "frc971/wpilib/imu_batch_generated.h"
#include "y2023/constants/constants_generated.h"
#include "y2023/vision/vision_util.h"

DEFINE_string(pi, "pi-7971-2", "Pi name to calibrate.");
DEFINE_bool(plot, false, "Whether to plot the resulting data.");
DEFINE_string(target_type, "charuco_diamond",
              "Type of target: aruco|charuco|charuco_diamond");
DEFINE_string(image_channel, "/camera", "Channel to listen for images on");
DEFINE_string(output_logs, "/tmp/calibration/",
              "Output folder for visualization logs.");
DEFINE_string(base_calibration, "",
              "Intrinsics (and optionally extrinsics) to use for extrinsics "
              "calibration.");
DEFINE_string(output_calibration, "",
              "Output json file to use for the resulting calibration "
              "(intrinsics and extrinsics).");

namespace frc971::vision {
namespace chrono = std::chrono;
using aos::distributed_clock;
using aos::monotonic_clock;

struct CalibrationAccumulatorState {
  CalibrationAccumulatorState(
      aos::SimulatedEventLoopFactory *factory, CalibrationData *data,
      aos::FlatbufferDetachedBuffer<calibration::CameraCalibration> *intrinsics)
      : factory(factory), data(data), intrinsics(intrinsics) {}
  aos::SimulatedEventLoopFactory *factory;
  CalibrationData *data;
  aos::FlatbufferDetachedBuffer<calibration::CameraCalibration> *intrinsics;
  std::unique_ptr<aos::EventLoop> imu_event_loop;
  std::unique_ptr<aos::EventLoop> pi_event_loop;
  std::unique_ptr<aos::EventLoop> logger_event_loop;
  std::unique_ptr<aos::logger::Logger> logger;
  std::unique_ptr<Calibration> extractor;
  void MaybeMakeExtractor() {
    if (imu_event_loop && pi_event_loop) {
      TargetType target_type = TargetTypeFromString(FLAGS_target_type);
      std::unique_ptr<aos::EventLoop> constants_event_loop =
          factory->MakeEventLoop("constants_fetcher", pi_event_loop->node());
      if (FLAGS_base_calibration.empty()) {
        frc971::constants::ConstantsFetcher<y2023::Constants> constants_fetcher(
            constants_event_loop.get());
        *intrinsics =
            aos::RecursiveCopyFlatBuffer(y2023::vision::FindCameraCalibration(
                constants_fetcher.constants(),
                pi_event_loop->node()->name()->string_view()));
      } else {
        *intrinsics = aos::JsonFileToFlatbuffer<calibration::CameraCalibration>(
            FLAGS_base_calibration);
      }
      extractor = std::make_unique<Calibration>(
          factory, pi_event_loop.get(), imu_event_loop.get(), FLAGS_pi,
          &intrinsics->message(), target_type, FLAGS_image_channel, data);
    }
  }
};

void Main(int argc, char **argv) {
  CalibrationData data;
  std::optional<uint16_t> pi_number =
      aos::network::ParsePiOrOrinNumber(FLAGS_pi);
  CHECK(pi_number);
  const std::string pi_name = absl::StrCat("pi", *pi_number);

  aos::FlatbufferDetachedBuffer<calibration::CameraCalibration> calibration =
      aos::FlatbufferDetachedBuffer<calibration::CameraCalibration>::Empty();
  {
    // Now, accumulate all the data into the data object.
    aos::logger::LogReader reader(
        aos::logger::SortParts(aos::logger::FindLogs(argc, argv)));
    reader.RemapLoggedChannel<foxglove::CompressedImage>("/pi1/camera");
    reader.RemapLoggedChannel<foxglove::CompressedImage>("/pi2/camera");
    reader.RemapLoggedChannel<foxglove::CompressedImage>("/pi3/camera");
    reader.RemapLoggedChannel<foxglove::CompressedImage>("/pi4/camera");
    reader.RemapLoggedChannel<foxglove::ImageAnnotations>("/pi1/camera");
    reader.RemapLoggedChannel<foxglove::ImageAnnotations>("/pi2/camera");
    reader.RemapLoggedChannel<foxglove::ImageAnnotations>("/pi3/camera");
    reader.RemapLoggedChannel<foxglove::ImageAnnotations>("/pi4/camera");

    aos::SimulatedEventLoopFactory factory(reader.configuration());
    reader.RegisterWithoutStarting(&factory);

    CHECK(aos::configuration::MultiNode(reader.configuration()));

    // Find the nodes we care about.
    const aos::Node *const imu_node =
        aos::configuration::GetNode(factory.configuration(), "imu");

    const aos::Node *const pi_node =
        aos::configuration::GetNode(factory.configuration(), pi_name);

    CalibrationAccumulatorState accumulator_state(&factory, &data,
                                                  &calibration);

    reader.OnStart(imu_node, [&accumulator_state, imu_node, &factory]() {
      accumulator_state.imu_event_loop =
          factory.MakeEventLoop("calibration", imu_node);
      accumulator_state.MaybeMakeExtractor();
    });

    reader.OnStart(imu_node, [&accumulator_state, pi_node, &factory]() {
      accumulator_state.pi_event_loop =
          factory.MakeEventLoop("logger", pi_node);
      accumulator_state.logger_event_loop =
          factory.MakeEventLoop("logger", pi_node);
      accumulator_state.logger = std::make_unique<aos::logger::Logger>(
          accumulator_state.logger_event_loop.get());
      accumulator_state.logger->StartLoggingOnRun(FLAGS_output_logs);
      accumulator_state.MaybeMakeExtractor();
    });

    factory.Run();

    reader.Deregister();
  }

  LOG(INFO) << "Done with event_loop running";
  CHECK(data.imu_samples_size() > 0) << "Didn't get any IMU data";
  CHECK(data.camera_samples_size() > 0) << "Didn't get any camera observations";

  // And now we have it, we can start processing it.
  // NOTE: For y2023, with no turret, pivot == imu

  // Define the mapping that takes imu frame (with z up) to camera frame (with z
  // pointing out)
  const Eigen::Quaterniond R_precam_cam(
      Eigen::AngleAxisd(-0.5 * M_PI, Eigen::Vector3d::UnitX()) *
      Eigen::AngleAxisd(-0.5 * M_PI, Eigen::Vector3d::UnitZ()));
  // Set up initial conditions for the pis that are reasonable
  Eigen::Quaternion<double> nominal_initial_orientation(
      Eigen::AngleAxisd(0.0, Eigen::Vector3d::UnitZ()));
  Eigen::Quaternion<double> nominal_pivot_to_camera(
      Eigen::AngleAxisd(0.5 * M_PI, Eigen::Vector3d::UnitX()) *
      Eigen::AngleAxisd(-0.75 * M_PI, Eigen::Vector3d::UnitY()));
  Eigen::Vector3d nominal_pivot_to_camera_translation(8.0, 8.0, 0.0);
  Eigen::Quaternion<double> nominal_board_to_world(
      Eigen::AngleAxisd(-0.5 * M_PI, Eigen::Vector3d::UnitX()));
  Eigen::Matrix<double, 6, 1> nominal_initial_state =
      Eigen::Matrix<double, 6, 1>::Zero();
  // Set y value to -1 m (approx distance from imu to the board/world)
  nominal_initial_state(1, 0) = 1.0;

  // If available, pull extrinsics from the calibration file
  const calibration::CameraCalibration *calib_msg = &calibration.message();
  if (calib_msg->has_fixed_extrinsics()) {
    LOG(INFO) << "Using extrinsiscs from calibration file as initial condition";
    const cv::Mat extrinsics_cv(
        4, 4, CV_32F,
        const_cast<void *>(static_cast<const void *>(
            calib_msg->fixed_extrinsics()->data()->data())));
    CHECK_EQ(extrinsics_cv.total(),
             calib_msg->fixed_extrinsics()->data()->size());
    Eigen::Matrix4d ext_mat;
    cv::cv2eigen(extrinsics_cv, ext_mat);
    Eigen::Affine3d extrinsics(ext_mat);
    Eigen::Affine3d H_camera_imu = extrinsics.inverse();
    nominal_pivot_to_camera = H_camera_imu.rotation();
    nominal_pivot_to_camera_translation = H_camera_imu.translation();
  }

  CalibrationParameters calibration_parameters;
  calibration_parameters.initial_orientation = nominal_initial_orientation;
  calibration_parameters.pivot_to_camera = nominal_pivot_to_camera;
  calibration_parameters.pivot_to_camera_translation =
      nominal_pivot_to_camera_translation;
  // Board to world rotation
  calibration_parameters.board_to_world = nominal_board_to_world;
  // Initial imu location (and velocity)
  calibration_parameters.initial_state = nominal_initial_state;
  calibration_parameters.has_pivot = false;

  // Show the inverse of pivot_to_camera, since camera_to_pivot tells where
  // the camera is with respect to the pivot frame
  const Eigen::Affine3d nominal_affine_pivot_to_camera =
      Eigen::Translation3d(calibration_parameters.pivot_to_camera_translation) *
      nominal_pivot_to_camera;
  const Eigen::Quaterniond nominal_camera_to_pivot_rotation(
      nominal_affine_pivot_to_camera.inverse().rotation());
  const Eigen::Vector3d nominal_camera_to_pivot_translation(
      nominal_affine_pivot_to_camera.inverse().translation());

  LOG(INFO) << "Initial Conditions for solver.  Assumes:\n"
            << "1) board origin is same as world, but rotated pi/2 about "
               "x-axis, so z points out\n"
            << "2) pivot origin matches imu origin (since there's no turret)\n"
            << "3) camera is offset from pivot (depends on which camera)";

  LOG(INFO) << "Nominal initial_orientation of imu w.r.t. world "
               "(angle-axis vector): "
            << frc971::controls::ToRotationVectorFromQuaternion(
                   nominal_initial_orientation)
                   .transpose();
  LOG(INFO) << "Nominal initial_state: \n"
            << "Position: "
            << nominal_initial_state.block<3, 1>(0, 0).transpose() << "\n"
            << "Velocity: "
            << nominal_initial_state.block<3, 1>(3, 0).transpose();
  LOG(INFO) << "Nominal camera_to_pivot rotation (angle-axis vector): "
            << frc971::controls::ToRotationVectorFromQuaternion(
                   nominal_camera_to_pivot_rotation)
                   .transpose();
  LOG(INFO) << "Nominal camera_to_pivot translation: "
            << nominal_camera_to_pivot_translation.transpose();

  aos::FlatbufferDetachedBuffer<calibration::CameraCalibration>
      solved_extrinsics = Solve(data, &calibration_parameters);
  calibration.mutable_message()->clear_fixed_extrinsics();
  calibration.mutable_message()->clear_turret_extrinsics();
  aos::FlatbufferDetachedBuffer<calibration::CameraCalibration>
      merged_calibration = aos::MergeFlatBuffers(&calibration.message(),
                                                 &solved_extrinsics.message());

  if (!FLAGS_output_calibration.empty()) {
    aos::WriteFlatbufferToJson(FLAGS_output_calibration, merged_calibration);
  } else {
    LOG(WARNING) << "Calibration filename not provided, so not saving it";
  }

  LOG(INFO) << "RESULTS OF CALIBRATION SOLVER:";
  std::cout << aos::FlatbufferToJson(&merged_calibration.message())
            << std::endl;

  LOG(INFO) << "initial_orientation of imu w.r.t. world (angle-axis vector): "
            << frc971::controls::ToRotationVectorFromQuaternion(
                   calibration_parameters.initial_orientation)
                   .transpose();
  LOG(INFO)
      << "initial_state (imu): \n"
      << "Position: "
      << calibration_parameters.initial_state.block<3, 1>(0, 0).transpose()
      << "\n"
      << "Velocity: "
      << calibration_parameters.initial_state.block<3, 1>(3, 0).transpose();

  const Eigen::Affine3d affine_pivot_to_camera =
      Eigen::Translation3d(calibration_parameters.pivot_to_camera_translation) *
      calibration_parameters.pivot_to_camera;
  const Eigen::Affine3d affine_camera_to_pivot =
      affine_pivot_to_camera.inverse();
  const Eigen::Quaterniond camera_to_pivot_rotation(
      affine_camera_to_pivot.rotation());
  const Eigen::Vector3d camera_to_pivot_translation(
      affine_camera_to_pivot.translation());
  LOG(INFO) << "camera to pivot(imu) rotation (angle-axis vec): "
            << frc971::controls::ToRotationVectorFromQuaternion(
                   camera_to_pivot_rotation)
                   .transpose();
  LOG(INFO) << "camera to pivot(imu) translation: "
            << camera_to_pivot_translation.transpose();
  LOG(INFO) << "board_to_world (rotation) "
            << frc971::controls::ToRotationVectorFromQuaternion(
                   calibration_parameters.board_to_world)
                   .transpose();
  LOG(INFO) << "accelerometer bias "
            << calibration_parameters.accelerometer_bias.transpose();
  LOG(INFO) << "gyro_bias " << calibration_parameters.gyro_bias.transpose();
  LOG(INFO) << "gravity " << 9.81 * calibration_parameters.gravity_scalar;

  LOG(INFO) << "Checking delta from nominal (initial condition) to solved "
               "values:";
  LOG(INFO) << "nominal_pivot_to_camera rotation: "
            << frc971::controls::ToRotationVectorFromQuaternion(
                   R_precam_cam * nominal_pivot_to_camera)
                   .transpose();
  LOG(INFO) << "solved pivot_to_camera rotation: "
            << frc971::controls::ToRotationVectorFromQuaternion(
                   R_precam_cam * calibration_parameters.pivot_to_camera)
                   .transpose();

  LOG(INFO) << "pivot_to_camera rotation delta (zero if the IC's match the "
               "solved value) "
            << frc971::controls::ToRotationVectorFromQuaternion(
                   calibration_parameters.pivot_to_camera *
                   nominal_pivot_to_camera.inverse())
                   .transpose();
  LOG(INFO) << "board_to_world rotation change "
            << frc971::controls::ToRotationVectorFromQuaternion(
                   calibration_parameters.board_to_world *
                   nominal_board_to_world.inverse())
                   .transpose();

  if (FLAGS_visualize) {
    LOG(INFO) << "Showing visualization";
    Visualize(data, calibration_parameters);
  }

  if (FLAGS_plot) {
    Plot(data, calibration_parameters);
  }
}  // namespace vision

}  // namespace frc971::vision

int main(int argc, char **argv) {
  aos::InitGoogle(&argc, &argv);

  frc971::vision::Main(argc, argv);
}
