// SPDX-FileCopyrightText: 2023 g10 code GmbH
// SPDX-Contributor: Carl Schwan <carl.schwan@gnupg.com>
// SPDX-License-Identifier: GPL-2.0-or-later

#include "emailcontroller.h"

#include <KLocalizedString>
#include <KMime/Message>
#include <MimeTreeParserCore/ObjectTreeParser>
#include <MimeTreeParserWidgets/MessageViewerDialog>
#include <QAction>
#include <QJsonArray>
#include <QJsonObject>
#include <QToolBar>
#include <QToolButton>

#include "draft/draftmanager.h"
#include "editor/composerwindow.h"
#include "editor/composerwindowfactory.h"
#include <utils.h>

using namespace Qt::Literals::StringLiterals;

QHttpServerResponse EmailController::viewEmailAction(const QHttpServerRequest &request)
{
    const auto email = QString::fromUtf8(Utils::findHeader(request.headers(), "X-EMAIL"));
    const auto displayName = QString::fromUtf8(Utils::findHeader(request.headers(), "X-NAME"));
    const auto bearerToken = Utils::findHeader(request.headers(), "X-TOKEN");

    const auto content = request.body();
    KMime::Message::Ptr message(new KMime::Message());
    message->setContent(KMime::CRLFtoLF(content));
    message->parse();

    auto dialog = new MimeTreeParser::Widgets::MessageViewerDialog({message});
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    auto toolBar = dialog->toolBar();
    toolBar->show();

    // spacer
    QWidget *spacer = new QWidget();
    spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    toolBar->addWidget(spacer);

    // reply
    auto replyAction = new QAction(QIcon::fromTheme(u"mail-reply-sender-symbolic"_s), i18nc("@action:button", "Reply"), toolBar);
    QObject::connect(replyAction, &QAction::triggered, dialog, [message, email, displayName, bearerToken](bool) {
        auto dialog = ComposerWindowFactory::self().create(email, displayName, bearerToken);
        dialog->reply(message);
        dialog->show();
    });
    toolBar->addAction(replyAction);
    auto widget = qobject_cast<QToolButton *>(toolBar->widgetForAction(replyAction));
    widget->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);

    // forward
    auto forwardAction = new QAction(QIcon::fromTheme(u"mail-forward-symbolic"_s), i18nc("@action:button", "Forward"), toolBar);
    QObject::connect(forwardAction, &QAction::triggered, dialog, [message, email, displayName, bearerToken](bool) {
        auto dialog = ComposerWindowFactory::self().create(email, displayName, bearerToken);
        dialog->reply(message);
        dialog->show();
    });
    toolBar->addAction(forwardAction);
    widget = qobject_cast<QToolButton *>(toolBar->widgetForAction(forwardAction));
    widget->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);

    dialog->show();

    return QHttpServerResponse(QJsonObject{{"status"_L1, "200"_L1}});
}

QHttpServerResponse EmailController::infoEmailAction(const QHttpServerRequest &request)
{
    qDebug() << "request received";
    const auto content = request.body();
    KMime::Message::Ptr message(new KMime::Message());
    message->setContent(KMime::CRLFtoLF(content));
    message->parse();

    MimeTreeParser::ObjectTreeParser treeParser;
    treeParser.parseObjectTree(message.get());

    return QHttpServerResponse(QJsonObject{
        {"status"_L1, "200"_L1},
        {"encrypted"_L1, treeParser.hasEncryptedParts()},
        {"signed"_L1, treeParser.hasSignedParts()},
        {"drafts"_L1, DraftManager::self().toJson()},
    });
}

QHttpServerResponse EmailController::newEmailAction(const QHttpServerRequest &request)
{
    const auto email = QString::fromUtf8(Utils::findHeader(request.headers(), "X-EMAIL"));
    const auto displayName = QString::fromUtf8(Utils::findHeader(request.headers(), "X-NAME"));
    const auto bearerToken = Utils::findHeader(request.headers(), "X-TOKEN");

    auto dialog = ComposerWindowFactory::self().create(email, displayName, bearerToken);
    dialog->show();

    return QHttpServerResponse(QJsonObject{{"status"_L1, "200"_L1}});
}

QHttpServerResponse EmailController::replyEmailAction(const QHttpServerRequest &request)
{
    const auto email = QString::fromUtf8(Utils::findHeader(request.headers(), "X-EMAIL"));
    const auto displayName = QString::fromUtf8(Utils::findHeader(request.headers(), "X-NAME"));
    const auto bearerToken = Utils::findHeader(request.headers(), "X-TOKEN");

    const auto content = request.body();
    KMime::Message::Ptr message(new KMime::Message());
    message->setContent(KMime::CRLFtoLF(content));
    message->parse();

    auto dialog = ComposerWindowFactory::self().create(email, displayName, bearerToken);
    dialog->reply(message);
    dialog->show();

    return QHttpServerResponse(QJsonObject{{"status"_L1, "200"_L1}});
}

QHttpServerResponse EmailController::forwardEmailAction(const QHttpServerRequest &request)
{
    const auto email = QString::fromUtf8(Utils::findHeader(request.headers(), "X-EMAIL"));
    const auto displayName = QString::fromUtf8(Utils::findHeader(request.headers(), "X-NAME"));
    const auto bearerToken = Utils::findHeader(request.headers(), "X-TOKEN");

    const auto content = request.body();
    KMime::Message::Ptr message(new KMime::Message());
    message->setContent(KMime::CRLFtoLF(content));
    message->parse();

    auto dialog = ComposerWindowFactory::self().create(email, displayName, bearerToken);
    dialog->forward(message);
    dialog->show();

    return QHttpServerResponse(QJsonObject{{"status"_L1, "200"_L1}});
}

QHttpServerResponse EmailController::draftAction(QString draftId, const QHttpServerRequest &request)
{
    const auto email = QString::fromUtf8(Utils::findHeader(request.headers(), "X-EMAIL"));
    const auto displayName = QString::fromUtf8(Utils::findHeader(request.headers(), "X-NAME"));
    const auto bearerToken = Utils::findHeader(request.headers(), "X-TOKEN");

    const auto draft = DraftManager::self().draftById(draftId.toUtf8());

    if (!draft.isValid()) {
        return QHttpServerResponse(QJsonObject{{"status"_L1, "404"_L1}}, QHttpServerResponse::StatusCode::NotFound);
    }

    if (request.method() == QHttpServerRequest::Method::Post) {
        // POST
        auto dialog = ComposerWindowFactory::self().create(email, displayName, bearerToken);
        dialog->setMessage(draft.mime());
        dialog->show();
    } else {
        // DELETE
        if (!DraftManager::self().remove(draft)) {
            return QHttpServerResponse(QJsonObject{{"status"_L1, "500"_L1}}, QHttpServerResponse::StatusCode::InternalServerError);
        }
    }

    return QHttpServerResponse(QJsonObject{{"status"_L1, "200"_L1}});
}
