#include "mainwindow.h"
#include <QVBoxLayout>
#include <QDir>
#include <QElapsedTimer>
#include "appcontext.h"
#include "canvas.h"
#include "logger.h"
#include "utils.h"
#include "abstractwidget.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_pStackedWidget(nullptr)
{
    setWindowFlags(Qt::FramelessWindowHint | Qt::Window);
    init_ui();

    Network &network = AppContext::instance().network();
    connect(&network, &Network::updateScreen, this, &MainWindow::onUpdateScreen);

    SerialPort &serialPort = AppContext::instance().serialPort();
    connect(&serialPort, &SerialPort::pageSwitch, this, &MainWindow::onPageSwitdh);
}

MainWindow::~MainWindow()
{

}

void MainWindow::init_ui()
{
    QWidget *pCentralWidget = new QWidget(this);
    setCentralWidget(pCentralWidget);
    QVBoxLayout *pMainLayout = new QVBoxLayout(pCentralWidget);
    m_pStackedWidget = new QStackedWidget(pCentralWidget);
    pMainLayout->addWidget(m_pStackedWidget);
    pMainLayout->setSpacing(0);
    pMainLayout->setContentsMargins(0, 0, 0, 0);

    ProjectManager &projectMgr = AppContext::instance().projectManager();
    int canvasCount = projectMgr.canvasCount();
    for(int i = 0; i < canvasCount; i++)
    {
        LOG_DEBUG("----------------canvas {}----------------", i);
        Canvas *pCanvas = new Canvas(projectMgr.canvas(i), m_pStackedWidget);
        pCanvas->resize(1280, 720);
        m_pStackedWidget->insertWidget(i, pCanvas);
    }

    m_pStackedWidget->setCurrentIndex(0);
}

void MainWindow::onUpdateScreen(const QJsonObject &obj)
{
    QElapsedTimer timer;
    timer.start(); // 开始计时

    ProjectManager &projectMgr = AppContext::instance().projectManager();
    int canvasCount = projectMgr.canvasCount();

    QList<QWidget *> widgets;
    QList<QStringList> parameters;

    for(int i = 0; i < canvasCount; i++)
    {
        Canvas *pCanvas = static_cast<Canvas *>(m_pStackedWidget->widget(i));
        if(!pCanvas) {
            LOG_ERROR("error current canvas");
            return;
        }

        widgets = pCanvas->widgetList();
        parameters = pCanvas->parameterList();

        if(widgets.count() != parameters.count()) {
            LOG_ERROR("error widget count and parameters count");
            return;
        }

        int count = widgets.count();

        for(int j = 0; j < count; j++)
        {
            AbstractWidget *pAbstractWidget = static_cast<AbstractWidget *>(widgets[j]);
            QStringList widgetParameters;
            QMetaObject::invokeMethod(pAbstractWidget, "parameters",
                                        Qt::AutoConnection, Q_RETURN_ARG(QStringList, widgetParameters));

            for(auto parameter : widgetParameters)
            {
                QMetaObject::invokeMethod(
                    pAbstractWidget,
                    "setValue",
                    Qt::AutoConnection,
                    Q_ARG(QString, parameter),
                    Q_ARG(QVariant, obj[parameter].toVariant()),
                    Q_ARG(QString, Utils::timestamp()));
            }

            if(pCanvas == m_pStackedWidget->currentWidget()) {
                QMetaObject::invokeMethod(pAbstractWidget, "redraw", Qt::AutoConnection);
            }
        }

    }

    qint64 duration = timer.elapsed(); // 获取经过的毫秒数
    LOG_DEBUG("update screen duration: {}ms", duration);
}

void MainWindow::onPageSwitdh(int state)
{
    ProjectManager &projectMgr = AppContext::instance().projectManager();
    int canvasCount = projectMgr.canvasCount();
    if (canvasCount <= 0)
        return;

    int currentIndex = m_pStackedWidget->currentIndex();
    int nextIndex = currentIndex;

    if (state < 0)
    {
        // 上一页
        nextIndex = (currentIndex - 1 + canvasCount) % canvasCount;
        LOG_INFO("page up: {}", nextIndex);
    }
    else if (state > 0)
    {
        // 下一页
        nextIndex = (currentIndex + 1) % canvasCount;
        LOG_INFO("page down: {}", nextIndex);
    }
    else
    {
        return; // state == 0 不翻页
    }

    m_pStackedWidget->setCurrentIndex(nextIndex);
}
