#include "model_select.h"
#include "ui_model_select.h"
#include <QProcess>
#include <QFile>
#include <QTextStream>

model_select::model_select(QWidget *parent) : QMainWindow(parent),
    ui(new Ui::model_select)
{
    ui->setupUi(this);
    send_time = 2;
    initsetting(); // 初始化设置
}

model_select::~model_select()
{
    delete ui;
}

void model_select::initsetting()
{
    this->setWindowTitle("开始设置");
    ui->port->setText("8899");
    ui->sim_time_wt->setText("100");
    ui->sim_time_qh->setText("100");
    connectNum = 0;
    // 初始化下拉菜单内容
    cbo_select_Init();
    // 连接信号槽
    // 创建监听的服务器对象
    ms = new QTcpServer(this);
    connect(ms, &QTcpServer::newConnection, this, [=]()
    {
        QTcpSocket *clientSocket = ms->nextPendingConnection();
        mstatus->setPixmap(QPixmap(":/accessibility.svg").scaled(20, 20));

        // 将客户端连接添加到连接管理中
        connectedClients[clientSocket] = "";

        // 增加处理连接的信号和槽
        connectClient(clientSocket);
        receive_Client(clientSocket); });

    // 状态栏处理动作
    mstatus = new QLabel;
    ui->statusbar->addWidget(new QLabel("是否有用户连接："));
    ui->statusbar->addWidget(mstatus);
}

void model_select::connectClient(QTcpSocket *clientSocket)
{
    connectNum++;
    qDebug() << "有用户连接：" << connectNum;
    connect(clientSocket, &QTcpSocket::disconnected, this, [=]()
    {
        clientSocket->close();
        connectedClients.remove(clientSocket);
        connectNum = 0;

        // 更新状态栏
        if (connectNum == 0) {
            mstatus->setPixmap(QPixmap(":/chat-bubble-xmark.svg").scaled(20, 20));

        } });


}

void model_select::openSimulinkModel(const QString &modelName)
{
    static QProcess *process = nullptr; // 静态变量，保持 MATLAB 进程

    if (!process) // 如果尚未启动 MATLAB 进程
    {
        process = new QProcess();
        QString program = "D:/app/matlab_2021b/bin/matlab.exe";
        QString model_path = "D:/model/tcp";
        model_path.replace("/", "\\\\");
        
        QStringList arguments;
        arguments << "-r" << QString("cd('%1'); run('%2');").arg(model_path, modelName)
                  << "-nosplash"
                  << "-nodesktop";

        // connect(process, &QProcess::finished, [=]()
        // {
        //     qDebug() << "MATLAB finished with exit code " << process->exitCode();
        //     process->deleteLater();
        //     process = nullptr; // 结束后将指针置为空以便下次重新启动
        // });

        process->start(program, arguments);

        if (!process->waitForStarted())
        {
            qDebug() << "Failed to start MATLAB!";
            delete process; // 启动失败，释放资源
            process = nullptr; // 将指针置为空
        }
        else
        {
            qDebug() << "MATLAB started successfully.";
        }
    }
    else // 如果正在运行 MATLAB 进程
    {
        QString model_path = "D:/model/tcp";
        QString command = QString("cd('%1'); run('%2');").arg(model_path, modelName);

        // 通过标准输入将命令发送到 MATLAB
        process->write(command.toUtf8() + "\n");
        process->waitForBytesWritten();
        qDebug() << "Sent command to running MATLAB: " << command;
    }
}


// 编写cbo_select的槽函数,下拉菜单的内容
void model_select::cbo_select_Init()
{
    // 代码解释:初始化model_select的下拉菜单内容,并设置当前选择项为"选择仿真模型"
    ui->cbo_model_select->addItem("选择仿真模型");
    ui->cbo_model_select->addItem("稳态模型");
    ui->cbo_model_select->addItem("切换模型");

    ui->cbo_model_select->setCurrentIndex(0);
    connect(ui->cbo_model_select, &QComboBox::currentIndexChanged, this, &model_select::cbo_select_changed);

    // 代码解释:初始化下拉菜单内容,并设置当前选择项为"选择仿真模型"
    ui->cbo_wt->addItem("选择稳态工况");
    ui->cbo_wt->addItem("27节");
    ui->cbo_wt->addItem("18节");
    ui->cbo_wt->addItem("12节");
    ui->cbo_wt->addItem("2.5节");
    ui->cbo_wt->addItem("9节");
    ui->cbo_wt->addItem("6节");
    ui->cbo_wt->addItem("6节静音");
    ui->cbo_wt->setCurrentIndex(0);
    connect(ui->cbo_wt, &QComboBox::currentIndexChanged, this, &model_select::cbo_wt_changed);
    // 代码解释:初始化工况下拉菜单内容,并设置当前选择项为"稳态工况"
    ui->cbo_condition->addItem("选择工况");
    connect(ui->cbo_condition, &QComboBox::currentIndexChanged, this, &model_select::cbo_condition_changed);

    ui->cbo_qh->addItem("选择切换工况");
    ui->cbo_qh->addItem("切换1");
    ui->cbo_qh->addItem("切换2");
    ui->cbo_qh->addItem("切换3");
    ui->cbo_qh->addItem("切换4");
    ui->cbo_qh->addItem("切换5");
    ui->cbo_qh->addItem("切换6");
    ui->cbo_qh->setCurrentIndex(0);
    //connect(ui->cbo_qh, &QComboBox::currentIndexChanged, this, &model_select::cbo_qh_changed);

    ui->cbo_lg->addItem("先开后关");
    ui->cbo_lg->addItem("预定顺序");
    ui->cbo_lg->setCurrentIndex(0);
    //connect(ui->cbo_lg, &QComboBox::currentIndexChanged, this, &model_select::cbo_lg_changed);

    ui->cbo_target->addItem("迅速");
    ui->cbo_target->addItem("平稳");
    ui->cbo_target->addItem("缓慢");
    ui->cbo_target->setCurrentIndex(0);
    //connect(ui->cbo_target, &QComboBox::currentIndexChanged, this, &model_select::cbo_target_changed);

    ui->line_gsf->setText("100");
    ui->line_gsp->setText("100");
    ui->line_nsp->setText("100");
    ui->line_nshf->setText("100");

    ui->cbo_pid->addItem("专家系统");
    ui->cbo_pid->addItem("PI");
    ui->cbo_pid->addItem("PID");
    ui->cbo_pid->setCurrentIndex(0);
    ui->cbo_pid_wt->addItem("专家系统");
    ui->cbo_pid_wt->addItem("PI");
    ui->cbo_pid_wt->addItem("PID");
    ui->cbo_pid_wt->setCurrentIndex(0);
    //connect(ui->cbo_pid, &QComboBox::currentIndexChanged, this, &model_select::cbo_pid_changed);
}

// slot函数,下拉菜单内容改变时触发
void model_select::on_btn_gsb_clicked()
{
    QString gsp_degree = ui->line_gsf_degree->text();
    QString pro_gsp_degree = "gsp_degree:";
    QString gsp_time = ui->line_gsb_start_time->text();
    QString pro_gsp_time= "gsp_time:";
    file_write(&pro_gsp_degree, &gsp_degree);
    file_write(&pro_gsp_time, &gsp_time);
}
void model_select::on_btn_gsf_clicked()
{
    QString gsf_degree = ui->line_gsf_degree->text();
    QString pro_gsf_degree = "gsf_degree:";
    QString gsf_time = ui->line_gsf_start_time->text();
    QString pro_gsf_time = "gsf_time:";
    file_write(&pro_gsf_degree, &gsf_degree);
    file_write(&pro_gsf_time, &gsf_time);
}

void model_select::cbo_select_changed(int index)
{
    QString modelAddress = "wt"; // 模型的地址大泵模型地址

    QString pro_dress = "model_address:";
    if (index == 1)
    {
        // 往txt中写入大泵稳态模型的地址
        modelAddress="wt";

    }
    else if (index == 2)
    {
        // 往txt中写入小泵稳态模型的地址
        modelAddress = "qh";
    }
    file_write(&pro_dress, &modelAddress);
    
    // ui->cbo_model_select->setDisabled(true);
    file_write(&pro_dress, &modelAddress);
}

void model_select::cbo_wt_changed(int index)
{
    QString wt_str = "condition_wt:";
    QString wt_num = "27";
    if (index == 1)
    {
        wt_num = "27";
    }
    else if (index == 2)
    {
        wt_num = "18";
    }
    else if (index == 3)
    {
        wt_num = "12";
    }
    else if (index == 4)
    {
        wt_num = "2.5";
    }
    else if (index == 5)
    {
        wt_num = "9";
    }
    else if (index == 6)
    {
        wt_num = "6";
    }
    else if (index == 7)
    {
        wt_num = "61";
    }
    file_write(&wt_str, &wt_num);

}

// slot函数,工况下拉菜单内容改变时触发
void model_select::cbo_condition_changed(int index)
{
    // 根据下拉菜单的选中项切换显示界面
    switch (index)
    {
    case 0:
        ui->condition->setCurrentIndex(0); // 显示第一个页面
        break;
    case 1:
        ui->condition->setCurrentIndex(1); // 显示第二个页面
        break;
    case 2:
        ui->condition->setCurrentIndex(2); // 显示第三个页面
        break;

    default:
        break;
    }

}
// 读取txt文件
void model_select::file_read()
{
    QFile file("D:/model/tcp/model_address.txt"); // 要读取的文件名

    // 以只读模式打开文件
    if (file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream in(&file);
        QString line = in.readLine(); // 读取一行
        while (!line.isNull())
        {
            // 处理每行数据
            qDebug() << "Line: " << line;
            line = in.readLine(); // 读取下一行
        }
        file.close(); // 关闭文件
    }
    else
    {
        // 处理文件打开失败的情况
        qDebug() << "Unable to open file for reading.";
    }
}
// 写入txt文件
void model_select::file_write(QString *prs_name, QString *msg)
{
    QString modelAddress = *prs_name + *msg;                               // 将指针解引用并连接字符串
    QFile file("D:/model/tcp/model_address.txt"); // 要写入的文件名

    // 以附加模式打开文件
    if (file.open(QIODevice::Append | QIODevice::Text))
    {
        QTextStream out(&file);
        out << modelAddress << '\n'; // 写入地址并换行
        file.close();                // 关闭文件
    }
    else
    {
        // 处理文件打开失败的情况
        qDebug() << "Unable to open file for writing.";
    }
}
void model_select::on_btn_link_clicked()
{
    unsigned short port = ui->port->text().toUShort(); // 获取端口号
    ms->listen(QHostAddress::Any, port);               // 监听所有地址上的指定端口
    // ui->setListen->setDisabled(true);                  // 禁用监听按钮
    // this->hide();
}
void model_select::on_btn_start_clicked()
{
    openSimulinkModel("tcp_test_link.m"); // 使用socket调用
    sim_time_wt = ui->sim_time_wt->text(); // 获取仿真时间
    QString pro_sim_time_wt="sim_time_wt:";
    file_write(&pro_sim_time_wt, &sim_time_wt); // 写入仿真时间到配置文件
    ui->btn_stop->setDisabled(false);  // 禁用停止按钮
    ui->btn_pause->setDisabled(false);  // 禁用暂停按钮
}
void model_select::on_btn_pause_clicked()//TCP发送pause命令
{
    QString serverMsg =(pause_flag > 0)?"pause": "continue";//
    if (serverMsg == "pause") {
        ui->btn_pause->setText("继续仿真");
    }
    else {
        ui->btn_pause->setText("暂停仿真");
    }
    for (auto clientSocket : connectedClients.keys()) {
        if (clientSocket->state() == QAbstractSocket::ConnectedState) {
            clientSocket->write(serverMsg.toUtf8());  // 发送消息
        }
    }
    pause_flag = (pause_flag > 0) ? -1 : 1;
}
void model_select::on_btn_stop_clicked()
{
    // 发送停止命令
    for (auto clientSocket : connectedClients.keys()) {
        if (clientSocket->state() == QAbstractSocket::ConnectedState) {
            clientSocket->write("stop");  // 发送消息
            ui->btn_stop->setDisabled(true);  // 禁用停止按钮
            ui->btn_pause->setDisabled(true);  // 禁用暂停按钮
        }
    }
}

void model_select::receive_Client(QTcpSocket *clientSocket)
{
    connect(clientSocket, &QTcpSocket::readyRead, this, [=]()
    {
        QByteArray data = clientSocket->readAll();
        if (data.isEmpty())
            return;

        char dataType = data.at(0);  // 读取前缀
        data.remove(0, 1);  // 移除前缀t

        if (dataType == 't') {
            // 处理文本数据
            QString message = QString::fromUtf8(data);
            qDebug() << "收到文本: " << message;
        }
        //处理数值数据
        else if (dataType == 'n') {
            // 处理数值数据
            QDataStream in(&data, QIODevice::ReadOnly);
            
            in >> send_time;
            qDebug() << "收到数值: " << send_time;
        }

        //发送信号到界面
        emit receive_msg(data);
        data.clear();  // 清空 data
    } );

}








