#include "coaldistributbarchartwidget.h"

#include <QDateTimeAxis>
#include <QList>
#include <QRandomGenerator>
#include <QScopedPointer>
#include <QTcpSocket>
#include <QVBoxLayout>
#include <QtCharts/QChart>

#include <QBarSeries>
#include <QBarSet>
#include <QChart>
#include <QChartView>
#include <QColor>
#include <QDateTimeAxis>
#include <QTimer>
#include <QVBoxLayout>

#include <memory>

CoalDistributBarChartWidget::CoalDistributBarChartWidget(QWidget* parent)
    : QWidget(parent)
    , m_tcpSocket(new QTcpSocket(this))
{
    initializeChart();

    m_systemSetting = new QSettings("system.ini", QSettings::IniFormat);

    connectTCPSocket();

    setupTimer();
}

CoalDistributBarChartWidget::~CoalDistributBarChartWidget()
{
    if (m_tcpSocket->state() == QAbstractSocket::ConnectedState) {
        m_tcpSocket->disconnectFromHost();
        m_tcpSocket->waitForDisconnected();
    }
    delete m_tcpSocket;
}

void CoalDistributBarChartWidget::updateChart()
{
    int radio = getCoalRatioByTCPSocket();
    if (radio < 0 || radio > 90) {
        return;
    }

    int setCount = m_set->count();

    m_set->remove(setCount - 1);
    m_set->insert(0, radio);
}

void CoalDistributBarChartWidget::initializeChart()
{
    // 创建图标
    m_chart = new QChart();

    m_chart->setBackgroundBrush(Qt::transparent);
    m_chart->setMargins(QMargins(0, 0, 0, 0));
    m_chart->legend()->hide();

    // 创建窗口并设置图表
    m_chartView = new QChartView(m_chart);
    m_chartView->setBackgroundBrush(Qt::transparent);
    m_chartView->setStyleSheet("background: transparent;"); // 使用样式表确保透明
    m_chartView->setRenderHint(QPainter::Antialiasing);
    m_chartView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    // 创建柱状图
    m_series = new QBarSeries();
    m_chart->addSeries(m_series);

    // 设置X轴为据煤溜摄像机距离
    QValueAxis* axisX = new QValueAxis;
    axisX->setRange(1, 300);
    axisX->setTickCount(10);
    axisX->setLabelFormat("%d");
    axisX->setLinePen(QPen(QColor(40, 46, 48)));
    axisX->setLabelsColor(QColor(151, 151, 151));

    axisX->setMinorTickCount(0); // 隐藏X轴刻度线
    axisX->setGridLineVisible(false);
    m_chart->addAxis(axisX, Qt::AlignBottom);
    m_series->attachAxis(axisX);

    // 设置Y轴为百分比
    QValueAxis* axisY = new QValueAxis;
    axisY->setTitleText("占比(%)");
    axisY->setTitleBrush(QBrush(QColor(151, 151, 151)));
    axisY->setLinePen(QPen(QColor(40, 46, 48)));
    axisY->setLabelsColor(QColor(151, 151, 151)); // 设置标签字体颜色为灰色
    axisY->setGridLineColor(QColor(40, 46, 48));
    axisY->setRange(0, 100);
    axisY->setTitleFont(QFont("Arial", 10)); // 设置标题字体
    axisY->setTitleVisible(true); // 确保标题可见
    m_chart->addAxis(axisY, Qt::AlignLeft);
    m_series->attachAxis(axisY);

    // 初始化默认数据集
    m_set = new QBarSet("测试1");
    m_set->setColor(QColor(95, 180, 255));
    m_set->setBorderColor(QColor(95, 180, 255));
    QRandomGenerator* generator = QRandomGenerator::global();
    for (int i = 0; i < 300; i++) {
        int randomNumber = generator->bounded(10, 51);
        *m_set << randomNumber;
    }
    m_series->append(m_set);

    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0); // 设置间距为0
    layout->addWidget(m_chartView);
    setLayout(layout);
}

void CoalDistributBarChartWidget::setupTimer()
{
    // 定时器设置
    m_timer = new QTimer(this);
    connect(m_timer, &QTimer::timeout, this,
        &CoalDistributBarChartWidget::updateChart);
    m_timer->start(1000); // 每秒更新一次
}

void CoalDistributBarChartWidget::connectTCPSocket()
{
    QString ipAddress = m_systemSetting->value("addr/ip").toString();
    quint16 port = m_systemSetting->value("addr/port").toInt();

    // 连接到 Modbus TCP 服务器
    m_tcpSocket->connectToHost(ipAddress, port);
    if (!m_tcpSocket->waitForConnected(5000)) {
        qDebug() << "连接失败：" << m_tcpSocket->errorString();
    }
}

int CoalDistributBarChartWidget::getCoalRatioByTCPSocket()
{
    if (m_tcpSocket->state() != QAbstractSocket::ConnectedState) {
        qDebug() << "未连接到服务器";
        return -1; // 返回错误值
    }

    // 构建 Modbus 请求
    const quint8 unitId = 1; // 单元 ID
    const quint8 functionCode = 0x03; // 读保持寄存器
    const quint16 startAddress = 699; // 寄存器地址
    const quint16 registerCount = 1; // 读取寄存器数量

    // 构建请求数据
    QByteArray request;
    QDataStream stream(&request, QIODevice::WriteOnly);
    stream.setByteOrder(QDataStream::BigEndian); // 使用大端字节序

    // 添加 Modbus 请求报文各部分
    stream << static_cast<quint16>(0x0004); // 事务 ID
    stream << static_cast<quint16>(0x0000); // 协议 ID
    stream << static_cast<quint16>(0x0006); // 剩余长度
    stream << unitId; // 单元 ID
    stream << functionCode; // 功能码
    stream << static_cast<quint16>(startAddress); // 寄存器地址（700 = 0x01BB）
    stream << registerCount; // 寄存器数量

    // 发送请求
    m_tcpSocket->write(request);
    if (!m_tcpSocket->waitForBytesWritten(5000)) {
        qDebug() << "写入请求失败：" << m_tcpSocket->errorString();
        return -1; // 返回错误值
    }

    // 等待响应
    if (!m_tcpSocket->waitForReadyRead(5000)) {
        qDebug() << "没有收到响应：" << m_tcpSocket->errorString();
        return -1; // 返回错误值
    }

    // 读取响应数据
    QByteArray response = m_tcpSocket->readAll();
    if (response.size() < 9) {
        qDebug() << "响应数据不完整";
        return -1; // 返回错误值
    }

    // 解析响应
    QDataStream responseStream(response);
    responseStream.setByteOrder(QDataStream::LittleEndian);
    quint16 responseTransactionId;
    responseStream >> responseTransactionId; // 事务 ID
    quint16 responseProtocolId;
    responseStream >> responseProtocolId; // 协议 ID
    quint16 responseLength;
    responseStream >> responseLength; // 剩余长度
    quint8 responseUnitId;
    responseStream >> responseUnitId; // 单元 ID
    quint8 responseFunctionCode;
    responseStream >> responseFunctionCode; // 功能码
    quint8 byteCount;
    responseStream >> byteCount; // 字节计数

    // 检查功能码和字节计数
    if (responseFunctionCode != functionCode || byteCount != 2) {
        qDebug() << "功能码或字节计数不匹配";
        return -1; // 返回错误值
    }

    // 获取并输出最后四个字节
    if (response.size() < 2) {
        qDebug() << "响应数据少于四个字节，无法获取最后四位";
    }

    QByteArray lastFourBytes = response.right(2); // 获取最后2个字节

    bool isOk;
    int decimalValue = lastFourBytes.toHex().toInt(&isOk, 16);

    return decimalValue; // 返回煤量占比
}

QByteArray CoalDistributBarChartWidget::createModbusTcpRequest()
{
    QByteArray request;
    QDataStream stream(&request, QIODevice::WriteOnly);
    stream.setByteOrder(QDataStream::BigEndian); // 使用大端字节序

    // 构建 Modbus TCP 请求
    quint16 transactionId = 0x0004; // 事务 ID
    quint16 protocolId = 0x0000; // 协议 ID
    quint16 length = 0x0006; // 剩余长度
    quint8 unitId = 0x01; // 单元 ID
    quint8 functionCode = 0x03; // 功能码
    quint8 byteCount = 0x02; // 字节计数
    quint16 registerAddress = 0x01BB; // 寄存器地址 700
    quint16 registerCount = 0x0001; // 寄存器数量

    // 写入数据
    stream << transactionId;
    stream << protocolId;
    stream << length;
    stream << unitId;
    stream << functionCode;
    stream << byteCount;
    stream << registerAddress;
    stream << registerCount;

    return request; // 返回生成的请求报文
}
