#include "MainWindow.h"

#include <QMessageBox>
#include <QVBoxLayout>
#include <QLabel>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QNetworkReply>
#include <QFile>
#include <QSettings>
#include <QFileInfo>
#include <QDir>
#include <QScreen>

#include "NetClient.h"
#include "DisplayWidget.h"
#include "TokenRequest.h"
#include "FileReceiver.h"

#include "ui_MainWindow.h"

MainWindow* s_instance = nullptr;

void clearFile() {
    const QString path = QApplication::applicationDirPath() + "/PhotoDisplay/paper/";
    QDir dir(path);
    dir.removeRecursively();
    dir.mkpath(path);
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    setWindowFlags(Qt::FramelessWindowHint);
    ui->setupUi(this);

    s_instance = this;

    clearFile();

    connect(qApp, &QApplication::screenAdded, this, &MainWindow::ScreenChange);
    connect(qApp, &QApplication::screenRemoved, this, &MainWindow::ScreenChange);

    if (!ParseSetting()) {
        QMessageBox::about(this, QString("错误"), QString("读取配置文件失败"));
        exit(-1);
    }
    qDebug() << __FUNCTION__ << "screen:" << QApplication::screens().count();
    for (int i = 0; i < m_setting.widgets.count(); ++i) {
        DisplayWidget* widget = new DisplayWidget(m_setting.widgets[i]);
        if (i == 0) {
            setCentralWidget(widget);
        }
        connect(widget, &DisplayWidget::ScreenGeometryChanged, this, &MainWindow::ScreenChange);
        m_widgets.append(widget);
    }

    ScreenChange();
    
    if (!zmqServer_.Start(m_setting.port)) {
        qDebug() << "QMainServer::Start listen failed"  << m_setting.port;
        return ;
    }
    connect(&zmqServer_, &ZMQServer::MessageReady, this, &MainWindow::OnHandleMessage);
    //connect(&m_udpSocket, &QUdpSocket::readyRead, this, &MainWindow::OnDataRead);

    m_tokenRequest = new TokenRequest(this);
}

MainWindow::~MainWindow() {
    //m_netClient->Stop();
    zmqServer_.Stop();
    delete ui;
    s_instance = nullptr;
}

MainWindow& MainWindow::Get() {
    return *s_instance;
}

void MainWindow::OnDataRead() {
   // while (m_udpSocket.hasPendingDatagrams()) {
    return;
    {
      //  QByteArray datagram;
     //   datagram.resize(m_udpSocket.pendingDatagramSize());

      //  QHostAddress peerHostAddress;
      //  m_udpSocket.readDatagram(datagram.data(), datagram.size(), &peerHostAddress);
        qDebug() << __FUNCTION__ <<"";
        QJsonDocument jsonDoc = QJsonDocument::fromJson("");
        if (!jsonDoc.isNull() && jsonDoc.isObject()) {
            QJsonObject jsonObj = jsonDoc.object();

            // 获取 cmd 字段的值
            if (jsonObj.contains("cmd")) {
                QString cmd = jsonObj["cmd"].toString();

                //if (cmd == "photo_ready") {
                 if (cmd == "trans") {
                    // 获取 file 和 download 字段的值
                    QString file = jsonObj["file"].toString();
                    QString download = jsonObj["download"].toString();
                    QString tag = jsonObj["info"].toString();

                    QString url = QString("http://%1:5000/download/%2").arg(m_serverIp, file);
                    QNetworkReply* reply = manager.get(QNetworkRequest(QUrl(url)));
                    connect(reply, &QNetworkReply::finished, [this, reply, file, download, tag]() {
                        if (reply->error() == QNetworkReply::NoError) {
                        // 获取 HTTP 状态码
                        int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

                        // 获取相应的数据
                        QByteArray imageData = reply->readAll();

                        const QString savePath = QApplication::applicationDirPath() + "/PhotoDisplay/paper/" + file;
                        // 保存图片到本地文件
                        QFile file(savePath);
                        file.open(QIODevice::WriteOnly);
                        file.write(imageData);
                        file.close();

                        ShowPaper(savePath, download, tag);


                        qDebug() << "下载完成" << savePath;
                    }
                    else {
                        qDebug() << "下载失败:" << reply->errorString();
                    }
                    });

                }
            }
        }
        else {
           /* QString message(datagram);
            if (datagram == "printServerBroadcast") {
                m_serverIp = peerHostAddress.toString();
            }*/
        }
    }
}

void MainWindow::ShowPaper(const QString& filePath, const QString& url, const QString& info) {
    QFileInfo fileInfo(filePath);
    QString fileName = fileInfo.completeBaseName();
    int num = fileName.toInt() - 1;
    int index = num % m_setting.count;

    qDebug() << __FUNCTION__ << "filePath:" << filePath << " url:" << url << " info:" << info;
    for (int i = 0; i < m_widgets.size(); ++i) {
        m_widgets[i]->SetPaper(filePath, url, info);
    }
}

void MainWindow::closeEvent(QCloseEvent* event) {
    zmqServer_.Stop();
    for (int i = 1; i < m_widgets.size(); ++i) {
        m_widgets[i]->close();
        m_widgets[i]->deleteLater();
    }
}

bool MainWindow::ParseSetting() {
    const QString jsonPath = QApplication::applicationDirPath() + "/PhotoDisplay/config.json";
    QFile file(jsonPath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Failed to open file";
        qApp->exit();
        return false;
    }

    QByteArray fileData = file.readAll();
    file.close();

    QJsonDocument jsonDoc = QJsonDocument::fromJson(fileData);

    if (jsonDoc.isNull()) {
        qDebug() << "json parse error";
        return false;
    }

    QJsonObject jsonObj = jsonDoc.object();
    m_setting.total = jsonObj.value("total").toInt();
    m_setting.start = jsonObj.value("start").toInt();
    m_setting.count = jsonObj.value("count").toInt();
    m_setting.port = jsonObj.value("port").toInt();
    m_serverIp = jsonObj.value("server").toString();

    QJsonArray widgetsArray = jsonObj.value("widgets").toArray();

    for (int i = 0; i < widgetsArray.size(); ++i) {
        Widget widget;
        QJsonObject widgetObj = widgetsArray.at(i).toObject();
        widget.x = widgetObj.value("x").toInt();
        widget.y = widgetObj.value("y").toInt();
        widget.width = widgetObj.value("width").toInt();
        widget.height = widgetObj.value("height").toInt();

        widget.bg = widgetObj.value("bg").toString();
        widget.anim = widgetObj.value("anim").toInt();

        widget.duration = widgetObj.value("duration").toInt();
        widget.tag = widgetObj.value("tag").toString();
        m_setting.widgets.emplace_back(std::move((widget)));
    }
    return true;
}

void MainWindow::OnHandleMessage(const QString& message) {
    if (message.isEmpty()) {
        qDebug() << __FUNCTION__ << "message is empty";
        return;
    }
    qDebug() << __FUNCTION__ << message;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(message.toUtf8());
    if (!jsonDoc.isNull() && jsonDoc.isObject()) {
        QJsonObject jsonObj = jsonDoc.object();

        // 获取 cmd 字段的值
        if (jsonObj.contains("cmd")) {
            QString cmd = jsonObj["cmd"].toString();

            //if (cmd == "photo_ready") {
            if (cmd == "trans") {
                // 获取 file 和 download 字段的值
                QString file = jsonObj["file"].toString();
                QString download = jsonObj["download"].toString();
                QString tag = jsonObj["info"].toString();

                QString url = QString("http://%1:5000/download/%2").arg(m_serverIp, file);
                QNetworkReply* reply = manager.get(QNetworkRequest(QUrl(url)));
                connect(reply, &QNetworkReply::finished, [this, reply, file, download, tag]() {
                    if (reply->error() == QNetworkReply::NoError) {
                        // 获取 HTTP 状态码
                        int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

                        // 获取相应的数据
                        QByteArray imageData = reply->readAll();

                        const QString savePath = QApplication::applicationDirPath() + "/PhotoDisplay/paper/" + file;
                        // 保存图片到本地文件
                        QFile file(savePath);
                        file.open(QIODevice::WriteOnly);
                        file.write(imageData);
                        file.close();

                        ShowPaper(savePath, download, tag);


                        qDebug() << "下载完成" << savePath;
                    }
                    else {
                        qDebug() << "下载失败:" << reply->errorString();
                    }
                    });

            }
        }
        else {
            qDebug() << "解析失败";
        }
    }
}

void MainWindow::ScreenChange() {
    const QList<QScreen*> screens = QApplication::screens();
    qDebug() << __FUNCTION__ << "screen:" << screens.count();
    int screenIndex = 0;
    for (int i = 0; i < m_setting.widgets.count(); ++i) {
        QWidget* widget = m_widgets[i];
        screenIndex = i;
        if (screenIndex >= screens.count()) {
          //  widget->hide();
           // continue;
            screenIndex = screens.count() - 1;
        }

        const QRect rect = screens[screenIndex]->geometry();

        QSize sz(qMin(m_setting.widgets[i].width, rect.width()), qMin(m_setting.widgets[i].height, rect.height()));

        QPoint pt(m_setting.widgets[i].x, m_setting.widgets[i].y);
        widget->setGeometry(QRect(pt, sz));
        widget->setFixedSize(sz);
        qDebug() << __FUNCTION__ << "i=" << i << ", screenIndex=" << screenIndex << " pt=" << pt << " size="<<sz;

        reinterpret_cast<DisplayWidget*>(widget)->SizeChange();

        if (i == 0) {
            widget = this;
            setGeometry(QRect(pt, sz));
            setFixedSize(sz);
        }


        widget->show();
    }
}