#include "NetClient.h"

#include <QCoreApplication>

#include <QHostAddress>
#include <QTcpSocket>
#include <QDataStream>
#include <QThread>

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QFileInfo>
#include <QFile>
#include <QDir>

#include "MainWindow.h"

NetClient::NetClient(QObject* param)
	: QObject(param)
	, m_udpSocket(new QUdpSocket(this)) {
}

bool NetClient::Start(quint16 port) {
	qDebug() << "NetClient::Start listen port=" << port;
	if (!m_udpSocket->bind(QHostAddress::AnyIPv4, port)) {
		qDebug() << "NetClient::Start listen failed";
		return false;
	}

	qDebug() << "UpdClient threaid:" << QThread::currentThread();
	connect(m_udpSocket, &QUdpSocket::readyRead, this, &NetClient::OnReadyRead);

  /*  QString ip;
    int serverPort = 0;
    MainWindow::Get().GetPaperIPAndPort(&ip, &serverPort);
	QString serverHost = QString("%1:%2").arg(ip).arg(serverPort);
	m_tcpClient->ConnectToServer(serverHost);*/
	return true;
}

void NetClient::Stop() {
	m_udpSocket->close();
}

bool NetClient::WriteMessage(const QString& cmd) {
	return m_udpSocket->writeDatagram(cmd.toUtf8(), QHostAddress::LocalHost, MainWindow::Get().GetRoopPort());

}

void NetClient::OnReadyRead() {
	qDebug() << "UpdClient threaid:" << QThread::currentThread();
	while (m_udpSocket->hasPendingDatagrams()) {
		QByteArray datagram;
		datagram.resize(m_udpSocket->pendingDatagramSize());
		QHostAddress sender;
		quint16 senderPort;

		m_udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
		ParseMessage(datagram);
		qDebug() << "Received: " << datagram;
	}
}

void NetClient::ParseMessage(const QByteArray& message) {
	QJsonParseError error;
	QJsonDocument jsonDoc = QJsonDocument::fromJson(message, &error);

	if (error.error != QJsonParseError::NoError) {
		qDebug() << "parse JSON failed" << error.errorString();
		return ;
	}

	if (!jsonDoc.isObject()) {
		qDebug() << "parse JSON failed json doc is not object";
		return;
	}

	QJsonObject jsonObj = jsonDoc.object();

	QString cmd = jsonObj.value("cmd").toString();

	// 打印解析结果
	qDebug()  << " cmd:" << cmd;

	if (cmd == "start") {
		MainWindow::Get().PlayDefualtVideo();
		const QString ip = jsonObj.value("printIp").toString();
	}
	else if (cmd == "face_swap") {
		QString fileName = jsonObj.value("file_name").toString();
		qDebug() << " cmd:" << cmd << " file_name:" << fileName;
		MainWindow::Get().DisplayPhoto(fileName);
	} else if (cmd == "header") {
        QString fileName = jsonObj.value("file_name").toString();
        qDebug() << " cmd:" << cmd << " file_name:" << fileName;
        MainWindow::Get().SendHeaderPhoto(fileName);
    } else if (cmd == "trans") {
        qDebug() << " cmd:" << cmd ;
        MainWindow::Get().Tranform(message);
    }
}

void NetClient::DownlaodFile(const QString& fileName) {
	QString url = "http://localhost:8000/" + fileName;
	QNetworkReply* reply = m_manager.get(QNetworkRequest(QUrl(url)));

	QObject::connect(reply, &QNetworkReply::finished, this, &NetClient::DownloadFinish);

}

void NetClient::DownloadFinish() {
	QNetworkReply* reply = reinterpret_cast<QNetworkReply*>(sender());
	if (reply->error() == QNetworkReply::NoError) {
		const QString fileName = QFileInfo(reply->url().path()).fileName();

		QString exeDirPath = qApp->applicationDirPath();
		QString targetDirPath = exeDirPath + "/images";

		QDir targetDir(targetDirPath);
		if (!targetDir.exists()) {
			if (!targetDir.mkpath(".")) {  // 创建目录及其上级目录
				qDebug() << "create dir failed";
				reply->deleteLater();
				return ;
			}
		}

		QString targetFilePath = targetDirPath + "/" + fileName;
		QFile file(targetFilePath);
		if (file.open(QIODevice::WriteOnly)) {
			file.write(reply->readAll());
			file.close();
			Q_EMIT FileReady(targetFilePath);
			qDebug() << "文件下载完成,保存为 downloaded_file.jpg";
		}
		else {
			qDebug() << "保存文件失败。";
		}
	}
	else {
		qDebug() << "下载失败:" << reply->errorString();
	}

	// 清理资源
	reply->deleteLater();
}