#include "modelec_gui/modelec_gui.hpp"
#include <rclcpp/rclcpp.hpp>
#include <QMenuBar>
#include <utility>
#include <modelec_utils/config.hpp>

namespace ModelecGUI {

    ROS2QtGUI::ROS2QtGUI(rclcpp::Node::SharedPtr node, QWidget *parent)
        : QMainWindow(parent), node_(std::move(node)), stackedWidget(new QStackedWidget(this)) {

        // Add pages to stack
        // resize(1200, 800);
        this->showFullScreen();

        home_page_ = new HomePage(get_node(), this);
        // odo_page_ = new OdoPage(get_node(), this);
        test_map_page_ = new TestMapPage(get_node(), this);
        map_page_ = new MapPage(get_node(), this);
        action_page_ = new ActionPage(get_node(), this);
        // alim_page_ = new AlimPage(get_node(), this);

        stackedWidget->addWidget(home_page_);
        // stackedWidget->addWidget(odo_page_);
        stackedWidget->addWidget(test_map_page_);
        stackedWidget->addWidget(map_page_);
        stackedWidget->addWidget(action_page_);
        // stackedWidget->addWidget(alim_page_);
        setCentralWidget(stackedWidget);

        setupMenu();

        connect(home_page_, &HomePage::TeamChoose, this, [this]()
        {
            stackedWidget->setCurrentWidget(map_page_);
        });

        if (Modelec::Config::get<bool>("config.ihm.sound.enabled", false))
        {
            RCLCPP_INFO(get_node()->get_logger(), "Sound enabled, setting up audio player");

            media_player_ = new QMediaPlayer(this);
            audio_output_ = new QAudioOutput(this);
            media_player_->setAudioOutput(audio_output_);

            audio_sub_ = node_->create_subscription<std_msgs::msg::String>(
                "audio/play", 10, [this](const std_msgs::msg::String::SharedPtr msg)
                {
                    if (Modelec::Config::has("config.ihm.sound." + msg->data + "@path"))
                    {
                        QString audio_file = QString::fromStdString(Modelec::Config::get<std::string>("config.ihm.sound." + msg->data + "@path"));
                        media_player_->setSource(QUrl::fromLocalFile(audio_file));
                        media_player_->play();
                    }
                });
        }

        quit_sub_ = node_->create_subscription<std_msgs::msg::Empty>(
            "gui/quit", 10, [this](const std_msgs::msg::Empty::SharedPtr)
            {
                close();
            });
    }

    void ROS2QtGUI::setupMenu() {
        QMenuBar *menuBar = this->menuBar();

        QMenu *optionsMenu = menuBar->addMenu("View");

        home_action_ = new QAction("Home", this);
        odo_action_ = new QAction("Odometrie", this);
        action_action_ = new QAction("Action", this);
        alim_action_ = new QAction("Alim", this);
        map_action_ = new QAction("Map", this);

        playmat_map_menu_ = new QMenu("playmat");
        playmat_map_ = new QAction("Map", this);
        playmat_grid_ = new QAction("Grid", this);

        toggle_show_obstacle_action_ = new QAction("Toggle Show Obstacle", this);

        exit_action_ = new QAction("Exit", this);

        optionsMenu->addAction(home_action_);
        optionsMenu->addAction(odo_action_);
        optionsMenu->addAction(action_action_);
        optionsMenu->addAction(alim_action_);
        optionsMenu->addSeparator();
        optionsMenu->addAction(map_action_);
        optionsMenu->addMenu(playmat_map_menu_);
        playmat_map_menu_->addAction(playmat_map_);
        playmat_map_menu_->addAction(playmat_grid_);
        optionsMenu->addAction(toggle_show_obstacle_action_);
        optionsMenu->addSeparator();
        optionsMenu->addAction(exit_action_);

        connect(home_action_, &QAction::triggered, this, [this]() {
            stackedWidget->setCurrentWidget(home_page_);
            home_page_->Init();
            map_page_->Reset();
        });

        connect(odo_action_, &QAction::triggered, this, [this]() {
            stackedWidget->setCurrentWidget(odo_page_);
        });

        connect(action_action_, &QAction::triggered, this, [this]() {
            stackedWidget->setCurrentWidget(action_page_);
        });

        connect(alim_action_, &QAction::triggered, this, [this]() {
            stackedWidget->setCurrentWidget(alim_page_);
        });

        connect(map_action_, &QAction::triggered, this, [this]() {
            stackedWidget->setCurrentWidget(test_map_page_);
            test_map_page_->StartLidar();
        });

        connect(playmat_map_, &QAction::triggered, this, [this]() {
            auto map_page = dynamic_cast<TestMapPage *>(stackedWidget->currentWidget());
            if (map_page) {
                map_page->setPlaymatMap();
            }
        });

        connect(playmat_grid_, &QAction::triggered, this, [this]() {
            auto map_page = dynamic_cast<TestMapPage *>(stackedWidget->currentWidget());
            if (map_page) {
                map_page->setPlaymatGrid();
            }
        });

        connect(toggle_show_obstacle_action_, &QAction::triggered, this, [this]() {
            auto map_page = dynamic_cast<TestMapPage *>(stackedWidget->currentWidget());
            if (map_page)
            {
                map_page->toggleShowObstacle();
            }
        });

        connect(exit_action_, &QAction::triggered, this, [this]() {
            close();
        });
    }

    ROS2QtGUI::~ROS2QtGUI() = default;

}
