/*
 * This file is part of smolbote. It's copyrighted by the contributors recorded
 * in the version control history of the file, available from its original
 * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
 *
 * SPDX-License-Identifier: GPL-3.0
 */

#include "navigationbar.h"
#include "configuration.h"
#include "urllineedit.h"
#include "util.h"
#include "webengine/webprofile.h"
#include "webengine/webview.h"
#include <QHBoxLayout>
#include <QMenu>
#include <QShortcut>
#include <QStyle>
#include <QToolBar>
#include <QToolButton>
#include <QWebEngineHistory>

NavigationBar::NavigationBar(QWidget *parent)
    : QToolBar(parent)
{
    setObjectName("navigationbar");
    setWindowTitle(tr("Navigation Toolbar"));
    Configuration config;

    // Back button
    backAction = addAction(Util::icon(QStyle::SP_ArrowBack), tr("Back"));
    config.shortcut<QAction>(*backAction, "shortcuts.navigation.back");
    connect(backAction, &QAction::triggered, this, [this]() {
        m_view->history()->back();
    });

    auto *backMenu = new QMenu(this);
    connect(backMenu, &QMenu::aboutToShow, this, [this, backMenu]() {
        backMenu->clear();
        const auto history = m_view->history()->backItems(10);
        for(const QWebEngineHistoryItem &item : history) {
            auto *action = backMenu->addAction(item.title());
            connect(action, &QAction::triggered, this, [item, this]() {
                m_view->history()->goToItem(item);
            });
        }
    });
    backAction->setMenu(backMenu);

    auto *backMenuShortcut = new QShortcut(QKeySequence(config.value<QString>("shortcuts.navigation.backmenu").value()), this);
    connect(backMenuShortcut, &QShortcut::activated, backMenu, [this, backMenu]() {
        if(backAction->isEnabled()) {
            auto *widget = this->widgetForAction(backAction);
            backMenu->exec(this->mapToGlobal(widget->pos() + QPoint(0, widget->height())));
        }
    });

    // Forward button
    forwardAction = addAction(Util::icon(QStyle::SP_ArrowForward), tr("Forward"));
    config.shortcut<QAction>(*forwardAction, "shortcuts.navigation.forward");
    connect(forwardAction, &QAction::triggered, this, [this]() {
        m_view->history()->forward();
    });

    auto *forwardMenu = new QMenu(this);
    connect(forwardMenu, &QMenu::aboutToShow, this, [this, forwardMenu]() {
        forwardMenu->clear();
        const auto history = m_view->history()->forwardItems(10);
        for(const QWebEngineHistoryItem &item : history) {
            auto *action = forwardMenu->addAction(item.title());
            connect(action, &QAction::triggered, this, [item, this]() {
                m_view->history()->goToItem(item);
            });
        }
    });
    forwardAction->setMenu(forwardMenu);

    auto *forwardMenuShortcut = new QShortcut(QKeySequence(config.value<QString>("shortcuts.navigation.forwardmenu").value()), this);
    connect(forwardMenuShortcut, &QShortcut::activated, forwardMenu, [this, forwardMenu]() {
        if(forwardAction->isEnabled()) {
            auto *widget = this->widgetForAction(forwardAction);
            forwardMenu->exec(this->mapToGlobal(widget->pos() + QPoint(0, widget->height())));
        }
    });

    // Stop/Refresh button
    stopReloadAction = addAction(Util::icon(QStyle::SP_BrowserReload), tr("Refresh"));
    config.shortcut<QAction>(*stopReloadAction, "shortcuts.navigation.refresh");
    connect(stopReloadAction, &QAction::triggered, this, [this]() {
        if(m_view->isLoaded())
            m_view->reload();
        else
            m_view->stop();
    });

    auto *reloadShortcut = new QShortcut(QKeySequence(config.value<QString>("shortcuts.navigation.reload").value()), this);
    connect(reloadShortcut, &QShortcut::activated, this, [this]() {
        m_view->triggerPageAction(QWebEnginePage::ReloadAndBypassCache);
    });

    // Home button
    homeAction = addAction(Util::icon(QStyle::SP_DirHomeIcon), tr("Home"));
    config.shortcut<QAction>(*homeAction, "shortcuts.navigation.home");
    connect(homeAction, &QAction::triggered, this, [this]() {
        m_view->load(m_view->profile()->homepage());
    });
}

void NavigationBar::connectWebView(WebView *view)
{
    m_view = view;

    disconnect(loadStartedConnection);
    disconnect(loadFinishedConnection);

    if(view == nullptr) {
        backAction->setEnabled(false);
        forwardAction->setEnabled(false);
        stopReloadAction->setEnabled(false);
        homeAction->setEnabled(false);

        return;
    }

    if(view->isLoaded()) {
        update_loadFinished();
    } else {
        update_loadStarted();
    }

    loadStartedConnection = connect(view, &QWebEngineView::loadStarted, this, &NavigationBar::update_loadStarted);
    loadFinishedConnection = connect(view, &QWebEngineView::loadFinished, this, &NavigationBar::update_loadFinished);
    stopReloadAction->setEnabled(true);
    homeAction->setEnabled(true);
}

void NavigationBar::update_loadStarted()
{
    backAction->setEnabled(m_view->history()->canGoForward());
    forwardAction->setEnabled(m_view->history()->canGoForward());
    stopReloadAction->setIcon(Util::icon(QStyle::SP_BrowserStop));
}

void NavigationBar::update_loadFinished()
{
    backAction->setEnabled(m_view->history()->canGoBack());
    forwardAction->setEnabled(m_view->history()->canGoForward());
    stopReloadAction->setIcon(Util::icon(QStyle::SP_BrowserReload));
}