#include "TcpClient.h"

#include "MainWindow.h"

TcpClient::TcpClient(QObject* parent)
    : QObject(parent) {
    m_socket = new QTcpSocket(this);

    // 连接信号槽
    connect(m_socket, &QTcpSocket::connected, this, &TcpClient::OnConnected);
    connect(m_socket, &QTcpSocket::disconnected, this, &TcpClient::OnDisconnected);
    connect(m_socket, &QTcpSocket::readyRead, this, &TcpClient::OnReadyRead);
    connect(m_socket, &QTcpSocket::stateChanged, this, &TcpClient::OnStateChanged);
    connect(m_socket, &QTcpSocket::errorOccurred, this, &TcpClient::OnError);

    // 设置心跳定时器
    m_heartbeatTimer = new QTimer(this);
    connect(m_heartbeatTimer, &QTimer::timeout, this, &TcpClient::SendHeartbeat);

    m_connectTimer = new QTimer(this);
    connect(m_connectTimer, &QTimer::timeout, this, &TcpClient::OnConntectTimeout);
}

TcpClient::~TcpClient() {
    disconnect();
    delete m_socket;
    delete m_heartbeatTimer;
}

bool TcpClient::ConnectToServer(const QString& address) {
    const auto state = m_socket->state();
    if (QAbstractSocket::UnconnectedState != state) {
        return true;
    }

    QStringList ipAndPort = address.split(":");
    if (ipAndPort.size() != 2) {
        return false;
    }

    m_ip = ipAndPort[0];
    m_port = ipAndPort[1].toInt();

    m_socket->connectToHost(QHostAddress(m_ip), m_port);
    return m_socket->waitForConnected();
}

void TcpClient::Disconnect() {
    m_socket->disconnectFromHost();
    m_heartbeatTimer->stop();
}

bool TcpClient::IsConnected() const {
    return QAbstractSocket::ConnectedState == m_socket->state();
}

bool TcpClient::IsNeedConnect() const {
    return QAbstractSocket::UnconnectedState == m_socket->state();
}

void TcpClient::OnConnected() {
    qDebug() << "Connected to server";

    m_connectTimer->stop();
    // 启动心跳定时器
    m_heartbeatTimer->start(5000); // 每 5 秒发送一次
    MainWindow::Get().SetNetStatus(1);
}

void TcpClient::OnDisconnected() {
    qDebug() << "Disconnected from server";
    m_connectTimer->start(3000);
}

void TcpClient::OnReadyRead() {
    QTcpSocket* tcpSocket = static_cast<QTcpSocket*>(sender());

    QDataStream receiveStream(tcpSocket);
    receiveStream.setVersion(QDataStream::Qt_6_2);

    QByteArray message;
    receiveStream >> message;
    
    QString cmd = QString::fromUtf8(message);
    qDebug() << "message: " << cmd;
    Q_EMIT MessageReceivered(cmd);

}

void TcpClient::OnStateChanged(QAbstractSocket::SocketState state) {
    if (QAbstractSocket::SocketState::ConnectedState == state) {
        m_connectTimer->start(3000);
    }
}

void TcpClient::OnError(QAbstractSocket::SocketError error) {
    qDebug() << "Socket error: " << m_socket->errorString();
    if (!m_connectTimer->isActive()) {
        m_connectTimer->start(3000);
    }
    MainWindow::Get().SetNetStatus(0);
    
}

void TcpClient::SendHeartbeat() {
    // 发送心跳数据
    QString heartbeatMsg = "Heartbeat";

    QByteArray sendData;
    QDataStream sendStream(&sendData, QIODevice::WriteOnly);

    // 设置版本号,可根据需求进行修改
    sendStream.setVersion(QDataStream::Qt_6_2);

    int messageSize = heartbeatMsg.toUtf8().size();

    // 写入包的大小
    sendStream << messageSize;

    // 写入实际数据
    sendStream.writeRawData(heartbeatMsg.toUtf8().constData(), messageSize);

    // 发送
    m_socket->write(sendData);
    m_socket->flush();
}

void TcpClient::OnConntectTimeout() {
    if (QAbstractSocket::ConnectingState == m_socket->state() ||
        QAbstractSocket::ConnectedState == m_socket->state()) {
        return;
    }
    m_socket->connectToHost(m_ip, m_port);
}