// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

// 项目自身文件
#include "PageMultiInfo.h"
#include "headerinfotablewidget.h"
#include "PageTableHeader.h"
#include "PageDetail.h"
#include "MacroDefinition.h"
#include "DeviceInfo.h"
#include "PageDriverControl.h"
#include "DevicePrint.h"
#include "DeviceInput.h"
#include "DeviceNetwork.h"
#include "DeviceCpu.h"
#include "DDLog.h"
#include "commonfunction.h"

// Dtk头文件
#include <DFontSizeManager>
#include <DMessageBox>
#include <DMenu>
#include <DMessageManager>

// Qt库文件
#include <QAction>
#include <QIcon>
#include <QLoggingCategory>
#include <QProcess>

DWIDGET_USE_NAMESPACE

using namespace DDLog;

#define LEAST_PAGE_HEIGHT 315  // PageMultiInfo最小高度 当小于这个高度时，上方的表格就要变小
static const int kAdjustHeight { 2 }; // 高度调节值

PageMultiInfo::PageMultiInfo(QWidget *parent)
    : PageInfo(parent)
    , mp_Label(new DLabel(this))
    , mp_HeaderInfoWidget(new DScrollArea(this))
    , mp_HeaderInfoContainer(new DWidget(mp_HeaderInfoWidget))
    , mp_HeaderInfoWidgetLay(new QVBoxLayout(mp_HeaderInfoContainer))
    , mp_Table(new PageTableHeader(this))
    , mp_Detail(new PageDetail(this))
{
    qCDebug(appLog) << "PageMultiInfo constructor start";
    m_deviceList.clear();
    m_menuControlList.clear();
    // 初始化界面布局
    initWidgets();

    // 连接槽函数
    connect(mp_Table, &PageTableHeader::itemClicked, this, &PageMultiInfo::slotItemClicked);
    connect(mp_Table, &PageTableHeader::refreshInfo, this, &PageMultiInfo::refreshInfo);
    connect(mp_Table, &PageTableHeader::exportInfo, this, &PageMultiInfo::exportInfo);
    connect(mp_Detail, &PageDetail::refreshInfo, this, &PageMultiInfo::refreshInfo);
    connect(mp_Detail, &PageDetail::exportInfo, this, &PageMultiInfo::exportInfo);
    connect(mp_Table, &PageTableHeader::enableDevice, this, &PageMultiInfo::slotEnableDevice);
    connect(mp_Table, &PageTableHeader::installDriver, this, &PageMultiInfo::slotActionUpdateDriver);
    connect(mp_Table, &PageTableHeader::uninstallDriver, this, &PageMultiInfo::slotActionRemoveDriver);
    connect(mp_Table, &PageTableHeader::wakeupMachine, this, &PageMultiInfo::slotWakeupMachine);
    connect(mp_Table, &PageTableHeader::signalCheckPrinterStatus, this, &PageMultiInfo::slotCheckPrinterStatus);
    emit refreshInfo();
}

PageMultiInfo::~PageMultiInfo()
{
    qCDebug(appLog) << "PageMultiInfo destructor start";
    // 清空指针
    if (mp_HeaderInfoWidget) {
        delete mp_HeaderInfoWidget;
        mp_HeaderInfoWidget = nullptr;
        mp_HeaderInfoContainer = nullptr;
    }
    if (mp_Table) {
        qCDebug(appLog) << "Deleting table";
        delete mp_Table;
        mp_Table = nullptr;
    }
    if (mp_Detail) {
        qCDebug(appLog) << "Deleting detail";
        delete mp_Detail;
        mp_Detail = nullptr;
    }
    m_deviceList.clear();
    m_menuControlList.clear();
    qCDebug(appLog) << "PageMultiInfo destructor end";
}

void PageMultiInfo::updateInfo(const QList<DeviceBaseInfo *> &lst)
{
    qCDebug(appLog) << "Updating multi device info, device count:" << lst.size();
    m_lstDevice.clear();
    m_lstDevice = lst;

    if (lst.size() < 1) {
        qCWarning(appLog) << "Empty device list provided";
        return;
    }

    // 当前为CPU页面，显示头部信息视图
    DeviceCpu *cpuInfo = dynamic_cast<DeviceCpu *>(lst.at(0));
    if (cpuInfo) {
        QList<QList<QPair<QString, QString>>> headerInfo;
        DeviceManager::instance()->getCpuHeaderInfo(headerInfo);
        clearLayout(mp_HeaderInfoWidgetLay);
        int defaultHeight { 0 };
        for (int i = 0; i < headerInfo.size(); ++i) {
            HeaderInfoTableWidget *headerWidget = new HeaderInfoTableWidget(mp_HeaderInfoWidget);
            headerWidget->updateData(headerInfo.at(i));
            mp_HeaderInfoWidgetLay->addWidget(headerWidget);
        }
        if (headerInfo.size() > 0 && headerInfo.at(0).size() > 0) {
            defaultHeight = headerInfo.at(0).size() * ROW_HEIGHT + kAdjustHeight;
        }
        mp_HeaderInfoWidget->setMaximumHeight(defaultHeight);
        mp_HeaderInfoWidget->resize(this->width(), defaultHeight);
        mp_HeaderInfoWidget->setVisible(true);
    } else {
        mp_HeaderInfoWidget->setVisible(false);
        mp_HeaderInfoWidget->setMaximumHeight(0);
    }

    m_deviceList.clear();
    m_menuControlList.clear();

    //  获取多个设备界面表格信息
    getTableListInfo(lst, m_deviceList, m_menuControlList);

    // 更新表格
    mp_Table->setVisible(true);
    mp_Table->setFixedHeight(TABLE_HEIGHT);
    mp_Table->updateTable(m_deviceList, m_menuControlList);
    if (Common::isHwPlatform()) {
        if (mp_Label->text() == tr("Storage") || mp_Label->text() == tr("Memory") || mp_Label->text() == tr("Monitor")) {
            mp_Table->setVisible(false);
            mp_Table->setFixedHeight(0);
        }
    }
    // 更新详细信息
    mp_Detail->showDeviceInfo(lst);
}

void PageMultiInfo::setLabel(const QString &itemstr)
{
    qCDebug(appLog) << "PageMultiInfo::setLabel, itemstr:" << itemstr;
    if (mp_Label) {
        mp_Label->setText(itemstr);

        // 设备类型加粗
        QFont font = mp_Label->font();
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
        font.setWeight(63);
#else
        font.setWeight(QFont::Bold);
#endif
        mp_Label->setFont(font);

        DFontSizeManager::instance()->bind(mp_Label, DFontSizeManager::T5);
    }
}

void PageMultiInfo::clearWidgets()
{
    qCDebug(appLog) << "PageMultiInfo::clearWidgets";
    m_lstDevice.clear();
    mp_Detail->clearWidget();
}

void PageMultiInfo::resizeEvent(QResizeEvent *e)
{
    qCDebug(appLog) << "PageMultiInfo::resizeEvent";
    if (m_lstDevice.size() < 1) {
        qCDebug(appLog) << "No device, skip resize";
        return PageInfo::resizeEvent(e);
    }

    // 先获取当前窗口大小
    int curHeight = this->height();
    if (curHeight < LEAST_PAGE_HEIGHT) {
        qCDebug(appLog) << "Height too small, resize table";
        //  获取多个设备界面表格信息
        if (Common::isHwPlatform()) {
            if (mp_Label->text() != tr("Storage") && mp_Label->text() != tr("Memory") && mp_Label->text() != tr("Monitor"))
                mp_Table->updateTable(m_deviceList, m_menuControlList, true, (LEAST_PAGE_HEIGHT - curHeight) / TREE_ROW_HEIGHT + 1);
        } else {
            mp_Table->updateTable(m_deviceList, m_menuControlList, true, (LEAST_PAGE_HEIGHT - curHeight) / TREE_ROW_HEIGHT + 1);
        }
    } else {
        qCDebug(appLog) << "Height is enough, resize table";
        //  获取多个设备界面表格信息
        if (Common::isHwPlatform()) {
            if (mp_Label->text() != tr("Storage") && mp_Label->text() != tr("Memory") && mp_Label->text() != tr("Monitor"))
                mp_Table->updateTable(m_deviceList, m_menuControlList, true, 0);
        } else {
            mp_Table->updateTable(m_deviceList, m_menuControlList, true, 0);
        }
    }

    return PageInfo::resizeEvent(e);
}

void PageMultiInfo::slotItemClicked(int row)
{
    qCDebug(appLog) << "PageMultiInfo::slotItemClicked, row:" << row;
    // 显示表格中选择设备的详细信息
    if (mp_Detail)
        mp_Detail->showInfoOfNum(row);
}

void PageMultiInfo::slotEnableDevice(int row, bool enable)
{
    qCDebug(appLog) << "PageMultiInfo::slotEnableDevice, row:" << row << "enable:" << enable;
    if (!mp_Detail) {
        qCWarning(appLog) << "mp_Detail is null";
        return;
    }

    // 禁用/启用设备
    EnableDeviceStatus res = mp_Detail->enableDevice(row, enable);

    // 除设置成功的情况，其他情况需要提示设置失败
    if (res == EDS_Success) {
        qCDebug(appLog) << "Enable device success";
        // 设置成功,更新界面
        emit updateUI();
    } else if (res == EDS_Faild) {
        qCWarning(appLog) << "Enable device failed";
        // 设置失败
        QString con;
        if (enable)
            // 无法启用设备
            con = tr("Failed to enable the device");
        else
            // 无法禁用设备
            con = tr("Failed to disable the device");

        // 禁用、启用失败提示
        DMessageManager::instance()->sendMessage(this->window(), QIcon::fromTheme("warning"), con);
    } else if (res == EDS_NoSerial) {
        qCWarning(appLog) << "Enable device failed, no serial";
        QString con = tr("Failed to disable it: unable to get the device SN");
        DMessageManager::instance()->sendMessage(this->window(), QIcon::fromTheme("warning"), con);
    }
}

void PageMultiInfo::slotWakeupMachine(int row, bool wakeup)
{
    qCDebug(appLog) << "PageMultiInfo::slotWakeupMachine, row:" << row << "wakeup:" << wakeup;
    if (!mp_Detail) {
        qCWarning(appLog) << "mp_Detail is null";
        return;
    }
    mp_Detail->setWakeupMachine(row, wakeup);
}

void PageMultiInfo::slotActionUpdateDriver(int row)
{
    qCDebug(appLog) << "Updating driver for device at row:" << row;
    DeviceBaseInfo *device = m_lstDevice[row];
    //打印设备卸载驱动时，通过dde-printer来操作
    if (nullptr != device && device->hardwareClass() == "printer") {
        qCDebug(appLog) << "Printer device detected, launching dde-printer";
        if (!QProcess::startDetached("dde-printer"))
            qCInfo(appLog) << "dde-printer startDetached error";
        return;
    }

    PageDriverControl *installDriver = new PageDriverControl(this, tr("Update Drivers"), true, device->name(), "");
    installDriver->show();
    connect(installDriver, &PageDriverControl::refreshInfo, this, &PageMultiInfo::refreshInfo);
}

void PageMultiInfo::slotActionRemoveDriver(int row)
{
    qCDebug(appLog) << "Removing driver for device at row:" << row;
    if (row < 0 || row >= m_lstDevice.size()) {
        qCWarning(appLog) << "Invalid row index:" << row;
        return;
    }
    DeviceBaseInfo *device = m_lstDevice[row];
    if (nullptr == device) {
        qCWarning(appLog) << "Null device at row:" << row;
        return;
    }
    QString printerVendor;
    QString printerModel;
    DevicePrint *printer = qobject_cast<DevicePrint *>(device);
    if (printer) {
        qCDebug(appLog) << "Printer device detected";
        printerVendor = printer->getVendor();
        printerModel = printer->getModel();
    }
    PageDriverControl *rmDriver = new PageDriverControl(this, tr("Uninstall Drivers"), false,
                                                        device->name(), device->driver(), printerVendor, printerModel);
    rmDriver->show();
    connect(rmDriver, &PageDriverControl::refreshInfo, this, &PageMultiInfo::refreshInfo);
}

void PageMultiInfo::slotCheckPrinterStatus(int row, bool &isPrinter, bool &isInstalled)
{
    qCDebug(appLog) << "PageMultiInfo::slotCheckPrinterStatus, row:" << row;
    DeviceBaseInfo *device = m_lstDevice.value(row, nullptr);
    if (!device) {
        qCWarning(appLog) << "No device at row:" << row;
        return;
    }
    DevicePrint *printer = qobject_cast<DevicePrint *>(device);
    if (printer) {
        qCDebug(appLog) << "Device is a printer";
        isPrinter = true;
        isInstalled = PageInfo::packageHasInstalled("dde-printer");
    }
}

void PageMultiInfo::initWidgets()
{
    qCDebug(appLog) << "PageMultiInfo::initWidgets";
    // 初始化界面布局
    QVBoxLayout *vLayout = new QVBoxLayout();
    QHBoxLayout *labelLayout = new QHBoxLayout();
    labelLayout->addSpacing(10);
    labelLayout->addWidget(mp_Label);

    // Label 距离上下控件的距离LABEL_MARGIN
    vLayout->addSpacing(LABEL_MARGIN);
    vLayout->addLayout(labelLayout);
    vLayout->addSpacing(LABEL_MARGIN);

    // 添加头部信息视图
    mp_HeaderInfoWidget->setWidget(mp_HeaderInfoContainer);
    mp_HeaderInfoWidget->setWidgetResizable(true);
    mp_HeaderInfoWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    mp_HeaderInfoWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    mp_HeaderInfoWidget->setFrameShape(QFrame::NoFrame);
    mp_HeaderInfoWidget->setMinimumHeight(0);
    mp_HeaderInfoWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    mp_HeaderInfoWidgetLay->setContentsMargins(0, 0, 0, 0);
    mp_HeaderInfoWidget->setVisible(false);
    vLayout->addWidget(mp_HeaderInfoWidget, 1);  // stretch=1，允许随窗口缩放

    mp_Table->setFixedHeight(TABLE_HEIGHT);
    vLayout->addWidget(mp_Table);
    vLayout->addWidget(mp_Detail);
    vLayout->setContentsMargins(10, 10, 10, 0);

    setLayout(vLayout);
}

void PageMultiInfo::getTableListInfo(const QList<DeviceBaseInfo *> &lst, QList<QStringList> &deviceList, QList<QStringList> &menuControlList)
{
    qCDebug(appLog) << "PageMultiInfo::getTableListInfo, device count:" << lst.size();
    //  获取多个设备界面表格信息
     if(lst[0] == nullptr) return;
    deviceList.append(lst[0]->getTableHeader());
    foreach (DeviceBaseInfo *info, lst) {
        // qCDebug(appLog) << "Processing device:" << info->name();
        if(info == nullptr) continue;
        QStringList lstDeviceInfo = info->getTableData();
        deviceList.append(lstDeviceInfo);

        QStringList menuControl;
        menuControl.append(info->canUninstall() ? "true" : "false");
        menuControl.append(info->canEnable() ? "true" : "false");
        DeviceInput *input = dynamic_cast<DeviceInput *>(info);
        if (input) {
            menuControl.append(input->canWakeupMachine() ? "true" : "false");
            menuControl.append(input->wakeupPath());
            if (info->name().contains("PS/2")) {
                menuControl.append(input->getBusInfo());
                menuControl.append(input->name());
                menuControl.append(input->hardwareClass());
                menuControl.append(input->getInterface());
            }
        }

        DeviceNetwork *network = dynamic_cast<DeviceNetwork *>(info);
        if (network) {
            menuControl.append(network->logicalName());
            menuControl.append(network->canDisable() ? "true" : "false");
        }

        menuControlList.append(menuControl);
    }
    qCDebug(appLog) << "PageMultiInfo::getTableListInfo end";
}

void PageMultiInfo::clearLayout(QLayout *layout)
{
    QLayoutItem *item;
    while ((item = layout->takeAt(0)) != nullptr) {
        // 如果布局项包含控件，删除该控件
        if (QWidget *widget = item->widget()) {
            widget->deleteLater();   // 安全删除，避免事件冲突
        }
        // 删除布局项本身（注意：如果 item 是子布局，需递归处理，本例仅处理直接控件）
        delete item;
    }
}
