#include "rescueloadwidget.h"
#include <QQuickWidget>
#include "qjsonarray.h"
#include "ui_rescueloadwidget.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QQuickView>
#include <QUrl>
#include <QRandomGenerator>
#include <QTextBlock>
#include <QtQml>
#include <QQmlContext>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QFileDialog>
#include <QMessageBox>
#include "tiqgeoserviceproviderfactory.h"
RescueLoadWidget::RescueLoadWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::RescueLoadWidget)
{
    ui->setupUi(this);
    initialModel(); // 初始化数据model
    initialUi(); // 初始化表格样式

    // 数据交互和视图设置
    rescueLoad = new RescueLoad(this);
    rescueLoad->startCommunication(); // todo: 转移到子线程中运行
    // rescueLoad->sendMessage(QString("Hello"));

    connect(rescueLoad, &RescueLoad::dataUpdate, rescueLoad, [=](ImsiData data){
        imsiDataModel->updateData(data);
    });

    // 地图组件, 必须在RescueLoad和ImsiDataModel初始化后加载
    openQLocationMap();
}

RescueLoadWidget::~RescueLoadWidget()
{
    ui->deviceDetail->clearContents();
    delete protoItem;
    delete standardItem;
    delete ui;
}

// 使用QLocation加载地图模块 (这里可以考虑换成内嵌网页地图)
void RescueLoadWidget::openQLocationMap() {
    Q_IMPORT_PLUGIN(TiQGeoServiceProviderFactory)
    QQuickView *qmlView = new QQuickView();
    // 列表和地图共享一个datamodel,减少重复的数据处理
    qmlView->rootContext()->setContextProperty("imsiDataModel", imsiDataModel); // 注意,先绑定属性,再设置qml
    qmlView->rootContext()->setContextProperty("imsiSelectModel", ui->deviceview->selectionModel()); // 注意,先绑定属性,再设置qml
    qmlView->setSource(QUrl("qrc:/places_map.qml"));
    QWidget *container = QWidget::createWindowContainer(qmlView, this);
    ui->mapGroup->setLayout(new QVBoxLayout);
    ui->mapGroup->layout()->addWidget(container);
    qDebug()<<"[搜救] 搜救地图开启"<<imsiDataModel->getDataMap().keys().size();
    // 接收QML的信号
    QObject*  object = (QObject* )qmlView->rootObject();
    // connect(object, SIGNAL(locationClicked(QString)), this, SLOT(updateDetailTable(QString)));
    QObject::connect(object, SIGNAL(indexClicked(int)), this, SLOT(tableIndexClicked(int)));
}

void RescueLoadWidget::tableIndexClicked(int row){
    emit ui->deviceview->clicked(imsiDataModel->index(row));
}

void RescueLoadWidget::initialUi()
{
    // 设备imsi列表样式
    setTable(ui->deviceview);
    setTable(ui->bnameview);
    setTable(ui->wnameview);
    // 单元格样式
    protoItem = new QTableWidgetItem;
    protoItem->setTextAlignment(Qt::AlignCenter);
    standardItem = new QStandardItem;
    standardItem->setTextAlignment(Qt::AlignCenter);
    QFont font = QFont("Microsoft YaHei UI", 12);
    protoItem->setFont(font);
    standardItem->setFont(font);
    setDeviceDetail(ui->deviceDetail);

}

void RescueLoadWidget::setTable(QTableView* tableView) {
    //  设置样式表
    tableView->setStyleSheet(
        "QTableView::item {"
        "    background-color: transparent;"
        "    color: white;"
        "}"
    );
    QFont font = QFont("Microsoft YaHei UI", 12);

    tableView->horizontalHeader()->setFont(font);
    tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 可拉伸填充
    tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);    //表头信息显示居中
    tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);//对第2列单独设置固定宽度
    tableView->setColumnWidth(1, 100);//设置固定宽度

    tableView->verticalHeader()->setFont(font);
    tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
    tableView->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
    tableView->verticalHeader()->setFixedWidth(35); // 行表头(序号)设置固定宽度
    // tableWidget->verticalHeader()->hide();              //将默认序号隐藏
    tableView->setShowGrid(true);
    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); // 不可编辑

    // 选中行更新详细信息
    tableView->setSelectionBehavior(QAbstractItemView::SelectRows); // 选中行

    // 单击后选中并显示详情,再次点击取消选中
    connect(tableView, &QTableView::clicked, this, [=](QModelIndex index) {
        static int preRow = -1; // 记录前一个点击事件所在行
        int curRow = index.row();
        QModelIndex imsiIndex = index.model()->index(curRow, 0); // note 第一列必须为imsi值
        QString imsi =tableView->model()->data(imsiIndex).toString();
        QItemSelectionModel* selectModel = tableView->selectionModel();
        if (curRow == preRow) {
            // 取消选中状态
            if (selectModel->isSelected(index)) {
                selectModel->select(index, QItemSelectionModel::Deselect | QItemSelectionModel::Rows);
                preRow = -1; //取消后重置,否则无法选中
                return;
            }
        }
        selectModel->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
        preRow = curRow;

        if (tableView == ui->deviceview){
            updateDetailTable(imsi);
        }
    });

    // 选中行更新名单编辑区
    connect(tableView->selectionModel(), &QItemSelectionModel::selectionChanged, tableView, [=]() {
        QModelIndexList selectedIndexes = tableView->selectionModel()->selectedIndexes();
        QAbstractItemModel* model = tableView->model();
        ui->namelistEdit->clear();

        QString selectedText;
        for (const QModelIndex &index : selectedIndexes) {
            if (index.column() == 0) {
                selectedText = model->data(index).toString();
                ui->namelistEdit->appendPlainText(selectedText.trimmed());
            }
        }
        ui->namelistEdit->show();
        // qDebug() << "选择状态变更: selcted: " << selectedIndexes;
    });
}




void RescueLoadWidget::initialModel()
{
    QStringList headers = QStringList()<<"IMSI"<<"运营商";
    wnamelistModel = new QStandardItemModel(this);
    wnamelistModel->setHorizontalHeaderLabels(headers);
    wnamelistModel->setColumnCount(2);
    ui->wnameview->setModel(wnamelistModel);

    bnamelistModel = new QStandardItemModel(this);
    bnamelistModel->setHorizontalHeaderLabels(headers);
    bnamelistModel->setColumnCount(2);
    ui->bnameview->setModel(bnamelistModel);

    imsiDataModel = new ImsiTableModel(this);
    ui->deviceview->setModel(imsiDataModel);
}


void RescueLoadWidget::setDeviceDetail(QTableWidget* deviceDetail) {
    // 设备详情表样式
    deviceDetail->setStyleSheet(
        "QTableWidget::item {"
        "    background-color: transparent;"
        "    color: white;"
        "}"
        );
    deviceDetail->verticalHeader()->setFont(QFont("Microsoft YaHei UI", 12));
    deviceDetail->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
    deviceDetail->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
    deviceDetail->setEditTriggers(QAbstractItemView::NoEditTriggers); // 不可编辑
    deviceDetail->setShowGrid(true);
    // 初始化
    for (int i=0; i<deviceDetail->rowCount(); i++) {
        QTableWidgetItem *item = protoItem->clone();
        deviceDetail->setItem(i, 0, item);
    }
    deviceDetail->show();
    qDebug() << "设备详细信息初始化完成";
}

// 更新指定imsi的详细信息
void RescueLoadWidget::updateDetailTable(const QString imsi)
{
    const QHash<QString, ImsiData>& dataMap = imsiDataModel->getDataMap();
    if (!dataMap.contains(imsi)) return;
    ImsiData data = imsiDataModel->getDataMap().value(imsi);
    // qDebug()<<"更新详细信息start: " << imsi;
    emit imsiDataModel->detailUpdated(imsi, data.longitude.toDouble(), data.latitude.toDouble());
    ui->deviceDetail->item(0, 0)->setText(data.imsi);
    ui->deviceDetail->item(1, 0)->setText(data.operatorName);
    ui->deviceDetail->item(2, 0)->setText(data.longitude);
    ui->deviceDetail->item(3, 0)->setText(data.latitude);
    ui->deviceDetail->item(4, 0)->setText(QString::number(data.altitude));
    ui->deviceDetail->item(5, 0)->setText(data.fcn);
    ui->deviceDetail->item(6, 0)->setText(QString::number(data.rssi));
    ui->deviceDetail->item(7, 0)->setText(data.createDate);
    ui->deviceDetail->show();

    // qDebug()<<"更新详细信息end: " << imsi;
}

slots void RescueLoadWidget::on_start4G_clicked()
{
    // 开启4g功放
    rescueLoad->sendMessage(QString("{\"cmd\": \"startCell\"}"));
    rescueLoad->sendMessage(QString("{\"cmd\": \"heartbeat\"}"));
    // 时间同步
    rescueLoad->syncTime();

}


slots void RescueLoadWidget::on_stop4G_clicked()
{
    rescueLoad->sendMessage(QString("{\"cmd\": \"stopCell\"}"));
}


slots void RescueLoadWidget::on_start5G_clicked()
{
    // 开启5g功放
    rescueLoad->sendMessage(QString("{\"cmd\": \"startCell_5g\"}"));
    rescueLoad->sendMessage(QString("{\"cmd\": \"heartbeat\"}"));
    // 时间同步
    rescueLoad->syncTime();
}


slots void RescueLoadWidget::on_stop5G_clicked()
{
    rescueLoad->sendMessage(QString("{\"cmd\": \"stopCell_5g\"}"));
}


slots void RescueLoadWidget::on_addblistBtn_clicked()
{
    QList<QString> namelistToSend = getNameListEditList(); // 输入量,用于更新namelist
    QString type = ui->namelistConfigType->currentText().toUpper();
    QString sendType;
    if (type.startsWith("ADD")) {
        sendType = "ADD";
    } else if (type.startsWith("SUB")) {
        sendType = "SUB";
    } else if (type.startsWith("SAVE")) {
        sendType = "SAVE";
    } else {
        return;
    }
    rescueLoad->sendNameList("block", sendType, QList<QString>(), namelistToSend);
    updateWBnamelist("B", sendType, namelistToSend);
}

slots void RescueLoadWidget::on_addwlistBtn_clicked()
{
    QList<QString> namelistToSend = getNameListEditList(); // 输入量,用于更新namelist
    QString type = ui->namelistConfigType->currentText().toUpper();
    QString sendType;
    if (type.startsWith("ADD")) {
        sendType = "ADD";
    } else if (type.startsWith("SUB")) {
        sendType = "SUB";
    } else if (type.startsWith("SAVE")) {
        sendType = "SAVE";
    } else {
        return;
    }
    rescueLoad->sendNameList("block", sendType, namelistToSend, QList<QString>());
    updateWBnamelist("W", sendType, namelistToSend);
}

/** 获取编辑区的imsi列表*/
QList<QString> RescueLoadWidget::getNameListEditList(){

    QTextBlock block = ui->namelistEdit->document()->firstBlock();
    QList<QString> namelist;
    while (block.isValid()) {
        QString tmp = block.text().trimmed();
        if (! tmp.isEmpty()) {
            namelist.append(tmp);
        }
        block = block.next();
    }
    return namelist;
}

// 更新黑名单和白名单的数据与显示
void RescueLoadWidget::updateWBnamelist(QString listType, QString sendType, QList<QString> &namelistToUpdate)
{
    QStandardItemModel *namelistModel = listType=="W"? wnamelistModel: bnamelistModel;
    QSet<QString> &namelistToShow = listType=="W"? wnamelist : bnamelist;
    QTableView *namelistView= listType=="W"? ui->wnameview : ui->bnameview;

    // 更新黑/白名单列表
    if (sendType == "ADD") { // 新增
        for(const QString &imsi: namelistToUpdate) {
            namelistToShow.insert(imsi);
        }
    } else if (sendType == "SUB") { // 删除
        for(const QString &imsi: namelistToUpdate) {
            namelistToShow.remove(imsi);
        }
    } else if (sendType == "SAVE") { // 替换现有在列表
        namelistToShow.clear();
        for(const QString &imsi: namelistToUpdate) {
            namelistToShow.insert(imsi);
        }
    }

    // 列表显示更新
    namelistModel->clear();
    namelistModel->setColumnCount(2);
    namelistModel->setRowCount(namelistToShow.size());
    namelistModel->setHorizontalHeaderLabels(QStringList()<<"IMSI"<<"运营商");
    namelistView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);//对第2列单独设置固定宽度
    namelistView->setColumnWidth(1, 100);//设置固定宽度
    int i = 0;
    for (const QString &imsi : namelistToShow) {
        QStandardItem *item1 =standardItem->clone();
        QStandardItem *item2 =standardItem->clone();
        item1->setText(imsi);
        item2->setText(ImsiData::getOperatorNameByImsi(imsi));
        namelistModel->setItem(i, 0, item1);
        namelistModel->setItem(i, 1, item2);
        i ++ ;
    }
    // qDebug() << "[搜救] 名单数据更新end"<< namelistModel->rowCount();
}



slots void RescueLoadWidget::on_ipportBtn_clicked()
{
    QString newIp = ui->ipEdit->text().trimmed();
    int newPort = ui->portEdit->text().trimmed().toInt();
    rescueLoad->remoteIp = newIp;
    rescueLoad->remotePort = newPort;
}


slots void RescueLoadWidget::on_saveFileButton_clicked()
{
    QString timeStr = QDateTime::currentDateTime().toString("yyyy-MM-ddThh-mm-ss");
    QString defaultPath = QString("%1/搜救信息%2.csv").arg(imsiDataModel->getSaveDir(), timeStr);
    QString filePath = QFileDialog::getSaveFileName(this, tr("保存文件"), defaultPath, tr("CSV 文件 (*.csv)"));
    qDebug()<< "[搜救] 文件保存"<< filePath;
    if (!filePath.isEmpty()) {
        imsiDataModel->saveDataListToCsv(filePath);
    }
}

slots void RescueLoadWidget::on_clearBtn_clicked()
{
    imsiDataModel->clearData();
}