#include "TcpClient.h"

//#include "mainWindow.h"
TcpClient::TcpClient(QObject *parent)
        : QObject(parent)
{
    connect(this, &TcpClient::restartSocket, this, &TcpClient::connectToServer);
}

void TcpClient::connectToServer(QString ip, int port) {
    try {

        this->ip_ = ip;
        this->port_ = port;
        this->tcp_ = new QTcpSocket;
        this->heartbeatTimer_ = new QTimer(this); //心跳包定时器
        QAbstractSocket::SocketState state = this->tcp_->state();

        if(QAbstractSocket::UnconnectedState == state) {
            emit sendTcpInfoSignals("未连接Socket服务器");
        }

        this->tcp_->connectToHost(ip, port); // Replace with actual server IP and port

        if(QAbstractSocket::ConnectingState == this->tcp_->state()) {
            emit sendTcpInfoSignals("正在连接Socket服务器...");
        }
        if (!this->tcp_->waitForConnected(2000))
        {
            emit sendTcpInfoSignals("链接服务端超时");
            // 5秒后尝试重新连接
            QTimer::singleShot(5000, this, [=](){
//                    this->tcp_ = new QTcpSocket;
                emit sendTcpInfoSignals("重新连接Socket");
                emit restartSocket(this->ip_, this->port_);
            });
            return;
        }
        else
        {
            if (!this->heartbeatTimer_->isActive()) {
                // 心跳包定时器启动
                this->heartbeatTimer_->start(3000);
            }
            emit sendTcpInfoSignals("链接服务端成功");
            // 连接失败
            connect(this->tcp_, &QTcpSocket::errorOccurred, this, [=](QAbstractSocket::SocketError err){
                emit sendTcpInfoSignals("链接服务端失败");    // 连接失败或其他错误，若服务器没有打开或连接失败，可以从这里会发出提示
            });
            // 断开连接
            connect(this->tcp_, &QTcpSocket::disconnected, this, [=](){
                emit sendTcpInfoSignals("服务端断开连接");
                this->tcp_->close();
                this->tcp_->deleteLater();
                this->tcp_ = nullptr;
                if (this->heartbeatTimer_->isActive())
                {
                    // 停止发送心跳包
                    this->heartbeatTimer_->stop();
                }

                // 5秒后尝试重新连接
                QTimer::singleShot(5000, this, [=](){
                    emit sendTcpInfoSignals("重新连接Socket");
                    emit restartSocket(this->ip_, this->port_);
                });

            });
            // 心跳信号
            connect(this->heartbeatTimer_, &QTimer::timeout, this, [=](){
                if (this->tcp_->state() == QAbstractSocket::ConnectedState) {
                    // 发送心跳包
                    this->tcp_->write("matrixai");
                }
            });

            // 接收到数据
            connect(this->tcp_, &QTcpSocket::readyRead, this, [=](){
                QByteArray jsonData = this->tcp_->readAll();

                jsonData.replace("}{", "}&{");
                QList<QByteArray> jsonDataList = jsonData.split('&');
                for (int i = 0; i < jsonDataList.size(); i++) {
//                    emit getTcpInfoSignals("TCP:" + QString(jsonDataList[i]));
                    QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonDataList[i]);
                    if (jsonDocument.isObject()) {
                        QJsonObject jsonObject = jsonDocument.object();
                        if (jsonObject["type"].toString() != carType && carType == "0")
                        {
                            // 来车
                            emit this->comeTrainSignals(true);
                            if (jsonObject["direction"].toInt(0) != 0) emit this->getDirectionSignals(jsonObject["direction"].toInt(0));
                            come_time = jsonObject["cometime"].toString();
                            carType = jsonObject["type"].toString();
//                            direction = jsonObject["direction"].toBool(false);
                        }
                        else if (jsonObject["type"].toString() != carType && carType == "1")
                        {
                            // 火车无
                            emit this->comeTrainSignals(false);
                            come_time = jsonObject["cometime"].toString();
                            carType = jsonObject["type"].toString();
                        }

                        if (jsonObject["type"].toString() == carType && jsonObject["direction"].toInt(0) != 0)
                        {
                            // 判断出火车方向
                            emit this->getDirectionSignals(jsonObject["direction"].toInt(0));
                        }
                    }
                }
            });
        }

        this->exit_flag = false;
        emit socketComplete(this->tcp_, ip, port);
    }
    catch (const std::exception &e) {
        emit sendTcpInfoSignals("链接服务端失败");
        this->exit_flag = true;
    }
}

void TcpClient::SetExitFlag(bool flag)
{
    this->exit_flag = flag;
}

void TcpClient::closeConnect()
{
    this->tcp_->close();
}
