#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>

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, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) {
		qDebug() << "NetClient::Start listen failed";
		return false;
	}

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

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

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();

	// 解析对象中的数据
	int code = jsonObj.value("code").toInt();
	QString cmd = jsonObj.value("cmd").toString();
	QString fileName = jsonObj.value("file_name").toString();

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

	if (code == 0 && cmd == "face_swap") {
		DownlaodFile(fileName);
	}
}

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();
}