#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "legacyapp.h"

#include <QBitmap>
#include <QPainter>
#include <QPixmap>
#include <QDebug>
#include <QThread>
#include <QMouseEvent>
#include <QMessageBox>
#include <QDesktopWidget>
#include <QtConcurrent/QtConcurrent>

MainWindow::MainWindow(LegacyApp *app, QWidget *parent) :
    QMainWindow(parent, Qt::Window | Qt::FramelessWindowHint), app(app),
    ui(new Ui::MainWindow), menuHoverWidget(nullptr), menuHoverWidgetAnimation(nullptr)
{
}

void MainWindow::Init() {
    ui->setupUi(this);

    status_frame = new StatusWidget(app, this);
    ui->content_layout->addWidget(status_frame);

    rusification_frame = new RusificationWidget(app, this);
    ui->content_layout->addWidget(rusification_frame);

    settings_frame = new SettingsWidget(app, this);
    ui->content_layout->addWidget(settings_frame);

    news_frame = new NewsWidget(app, this);
    ui->content_layout->addWidget(news_frame);

    help_frame = new HelpWidget(app, this);
    ui->content_layout->addWidget(help_frame);

    hideAllContentWidgets();
    status_frame->show();

    changeFontSizeRecursive(100, this);

    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    background = new QPixmap();
    background->load(":/assets/backgrounds/bg" + QString::number(qrand() % MAX_PIXMAP_ID + 1) + ".png");
    setupWindowBackgroundAndMask();
    setupMenuHoverWidget();

    updateGeometry();
    repaint();

    background_update_timer.setInterval(30 * 1000);
    connect(&background_update_timer, &QTimer::timeout, this, &MainWindow::randomChangeBackground);
    background_update_timer.start();
    ui->centralWidget->setStyleSheet("");
    show();
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        dragPosition = event->globalPos() - frameGeometry().topLeft();
        event->accept();
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        move(event->globalPos() - dragPosition);
        event->accept();
    }
}

void MainWindow::resizeEvent(QResizeEvent * event)
{
    int width = event->size().width();
    int height = event->size().height();

    ui->menu_widget->move(width * 675 / 2000, height * 80 / 1296);
    ui->menu_widget->resize(width * 1260 / 2000, height * 90 / 1296);

    ui->content_area->move(width * 25 / 2000, height * 250 / 1296);
    ui->content_area->resize(width * 1950 / 2000, height * 1000 / 1296);
    setupWindowBackgroundAndMask();
}

void MainWindow::randomChangeBackground()
{
    if (!qApp)
        return;

    qDebug() << "Starting background update";

    if (fade_animation_timer.isActive()) {
        qDebug() << "MainWindow::startBackgroundUpdate() - cannot start, because update is still active";
        return;
    }

    next_pixmap_opacity = 0;
    int next_pixmap_id = qrand() % MAX_PIXMAP_ID + 1;

    if (!next_pixmap)
        next_pixmap = new QPixmap();

    next_pixmap->load(":/assets/backgrounds/bg" + QString::number(next_pixmap_id) + ".png");
    qDebug() << "Next pixmap id" << next_pixmap_id << "!";

    if (next_pixmap->isNull()) {
        qDebug() << "Incorrect pixmap id " << next_pixmap_id << "!";
        return;
    }

    QtConcurrent::run([this](){
        qDebug() << "Starting background update";
        while (next_pixmap_opacity < 1 && qApp) {
            if (!qApp)
                return;

            QPainter painter;
            painter.begin(background);
            painter.setOpacity(next_pixmap_opacity);
            painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
            painter.drawPixmap(0,0, *next_pixmap);
            painter.end();

            setupWindowBackgroundAndMask();
            next_pixmap_opacity += 0.005;
            QThread::msleep(50);
        }
        qDebug() << "Background update finished";
    });
}


MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_menuentry_1_common_clicked()
{
    hideAllContentWidgets();
    status_frame->show();
}

void MainWindow::on_menuentry_2_common_clicked()
{
    hideAllContentWidgets();
    settings_frame->show();
}

void MainWindow::on_menuentry_3_common_clicked()
{
    hideAllContentWidgets();
    rusification_frame->show();
}

void MainWindow::on_menuentry_4_common_clicked()
{
    hideAllContentWidgets();
    news_frame->show();
}

void MainWindow::on_menuentry_5_common_clicked()
{
    hideAllContentWidgets();
    help_frame->show();
}

void MainWindow::onHoverMenuentry()
{
    moveMenuHoverWidget(MenuEntry::getHoverLabel());
}

void MainWindow::setupWindowBackgroundAndMask()
{
    current_bg = background->scaled(width(), height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    current_mask = current_bg.mask();
    setMask(current_mask);

    QPalette palette;
    palette.setBrush(QPalette::Window, current_bg);
    setPalette(palette);
}

void MainWindow::setupMenuHoverWidget()
{
    menuHoverWidget = new QWidget(ui->menu_widget);
    menuHoverWidget->setStyleSheet("background-color: rgba(55, 37, 31, 250);");
    menuHoverWidget->resize(0, 0);

    connect(ui->menuentry_1_common, &MenuEntry::hover_label_changed, this, &MainWindow::onHoverMenuentry);
    connect(ui->menuentry_2_common, &MenuEntry::hover_label_changed, this, &MainWindow::onHoverMenuentry);
    connect(ui->menuentry_3_common, &MenuEntry::hover_label_changed, this, &MainWindow::onHoverMenuentry);
    connect(ui->menuentry_4_common, &MenuEntry::hover_label_changed, this, &MainWindow::onHoverMenuentry);
    connect(ui->menuentry_5_common, &MenuEntry::hover_label_changed, this, &MainWindow::onHoverMenuentry);

    MenuEntry::setActiveLabel(ui->menuentry_1_common);
    menu_hover_checker_timer.setInterval(500);
    connect(&menu_hover_checker_timer, &QTimer::timeout, this, &MainWindow::checkMenuIsHovered);
    menu_hover_checker_timer.start();
}

void MainWindow::moveMenuHoverWidget(MenuEntry *target)
{
    if (menuHoverWidget->size() == QSize(0, 0)) {
        menuHoverWidget->resize(target->size() + QSize(10, 0));
        menuHoverWidget->move(target->pos() + QPoint(-5, 0));
    } else {
        if (menuHoverWidgetAnimation == nullptr)
            menuHoverWidgetAnimation = new QPropertyAnimation(menuHoverWidget, "geometry");
        else
            menuHoverWidgetAnimation->stop();

        menuHoverWidgetAnimation->setDuration(200);
        menuHoverWidgetAnimation->setStartValue(QRect(menuHoverWidget->pos(), menuHoverWidget->size()));
        menuHoverWidgetAnimation->setEndValue(QRect(target->pos() + QPoint(-5, 0), target->size() + QSize(10, 0)));
        menuHoverWidgetAnimation->start();
    }

    ui->menuentry_1_common->raise();
    ui->menuentry_2_common->raise();
    ui->menuentry_3_common->raise();
    ui->menuentry_4_common->raise();
    ui->menuentry_5_common->raise();

}

void MainWindow::checkMenuIsHovered()
{
    QPoint pos = QCursor::pos();
    QWidget *hovered = qApp->widgetAt(pos);
    if (!hovered || hovered->objectName().size() < 4 ||
            (hovered->objectName().left(9) != "menuentry" && hovered->objectName() != "menu_widget")) {
        moveMenuHoverWidget(MenuEntry::getActiveLabel());
        MenuEntry::setHoverLabel(nullptr);
    }
}

void MainWindow::hideAllContentWidgets()
{
    status_frame->hide();
    rusification_frame->hide();
    settings_frame->hide();
    news_frame->hide();
    help_frame->hide();
}

void MainWindow::changeFontSizeRecursive(size_t percent, QWidget *widget)
{
    if (!widget)
        return;
    QFont widget_font = widget->font();
    QString widget_name = widget->objectName();

    if (widget_name.contains("_common"))
        widget_font.setPixelSize(common_font_size * percent / 100);
    if (widget_name.contains("_title"))
        widget_font.setPixelSize(title_font_size * percent / 100);
    if (widget_name.contains("_supertitle"))
        widget_font.setPixelSize(supertitle_font_size * percent / 100);
    if (widget_name.contains("_bigbutton"))
        widget_font.setPixelSize(bigbutton_font_size * percent / 100);

    widget->setFont(widget_font);

    for (QObject* child : widget->children())
        if (child->isWidgetType()) {
            QWidget* w = qobject_cast<QWidget *>(child);
            changeFontSizeRecursive(percent, w);
            w->resize(w->sizeHint());
        }
}

void MainWindow::on_closeButton_clicked()
{
    hide();
    qApp->quit();
}

void MainWindow::on_minimizeButton_clicked()
{
    setWindowState(Qt::WindowMinimized);
}
