// src/devicediscovery.cpp
#include "devicediscovery.h"
#include "stellarmatedevice.h"

#include <QDesktopServices>
#include <QUrl>
#include <QProcess>

#include <QNetworkReply>
#include <QNetworkRequest>
#include <QJsonDocument>
#include <QJsonObject>
#include <QHostAddress>
#include <QNetworkInterface>
#include <QHostInfo>
#include <QDebug>
#include <QTimer>
#include <QJsonArray>
#include <QtConcurrent>
#include <QFuture>

/* Static verbose flag initialization */
bool DeviceDiscovery::s_verbose = false;

DeviceDiscovery::DeviceDiscovery(QObject *parent)
    : QAbstractListModel(parent), m_networkManager(new QNetworkAccessManager(this)), m_discoveryTimer(new QTimer(this)),
      m_mdnsTimer(new QTimer(this)) // Initialize mDNS timer
    ,
      m_statusUpdateTimer(new QTimer(this)),
      m_udpSocket(new QUdpSocket(this)), m_mdns(nullptr) // Start with nullptr, will initialize async
    ,
      m_isScanning(false), m_mdnsPhase(false) // Initialize mDNS phase flag
    ,
      m_statusText("Ready to scan for StellarMate devices"), m_pendingRequests(0), m_mdnsDevicesFound(0), m_hasWifiDongle(false),
      m_useInternalWifi(true),  m_initialDeviceListWasEmpty(true), m_mdnsInitialized(false), m_pendingStartDiscovery(false)
{
    m_discoveryTimer->setSingleShot(true);
    m_discoveryTimer->setInterval(30000); // 30 seconds timeout for network scan
    connect(m_discoveryTimer, &QTimer::timeout, this, &DeviceDiscovery::onDiscoveryTimeout);

    // Setup mDNS timer (allow time for mDNS responses and subsequent API calls)
    m_mdnsTimer->setSingleShot(true);
    m_mdnsTimer->setInterval(10000); // 10 seconds for mDNS responses and API calls
    connect(m_mdnsTimer, &QTimer::timeout, this, &DeviceDiscovery::onMdnsTimeout);

    m_statusUpdateTimer->setInterval(10000); // 10 seconds
    connect(m_statusUpdateTimer, &QTimer::timeout, this, &DeviceDiscovery::onPeriodicStatusUpdate);

    // Initialize mDNS asynchronously using QtConcurrent
    m_mdnsInitFuture = QtConcurrent::run([this]()
    {
        // This blocks but on worker thread - won't block UI
        qMDNS* mdns = qMDNS::getInstance();

        // Move back to main thread to connect signals and set pointer
        QMetaObject::invokeMethod(this, [this, mdns]()
        {
            m_mdns = mdns;
            m_mdnsInitialized = true;

            // Connect to mDNS signals
            connect(m_mdns, &qMDNS::hostFound, this, &DeviceDiscovery::onMdnsHostFound);
            connect(m_mdns, &qMDNS::serviceFound, this, &DeviceDiscovery::onMdnsServiceFound);

            if (s_verbose)
                qDebug() << "mDNS initialized asynchronously";

            // If startDiscovery was called before init finished, start mDNS discovery now
            if (m_pendingStartDiscovery)
            {
                if (s_verbose)
                    qDebug() << "mDNS initialized, starting pending mDNS discovery";
                startMdnsDiscovery();
            }
        }, Qt::QueuedConnection);
    });

    // Initialize m_deviceInfoStatus and m_tempDevices are implicitly initialized
}

DeviceDiscovery::~DeviceDiscovery()
{
    stopPeriodicStatusUpdates();
}

/**
 * Sets the verbose logging mode for DeviceDiscovery
 */
void DeviceDiscovery::setVerbose(bool verbose)
{
    s_verbose = verbose;
}

/**
 * Returns whether verbose logging is enabled for DeviceDiscovery
 */
bool DeviceDiscovery::isVerbose()
{
    return s_verbose;
}

void DeviceDiscovery::startPeriodicStatusUpdates()
{
    if (!m_statusUpdateTimer->isActive())
    {
        if (s_verbose)
            qDebug() << "Starting periodic status updates every 10 seconds";
        m_statusUpdateTimer->start();
        // Do an immediate first check
        onPeriodicStatusUpdate();
    }
}

void DeviceDiscovery::stopPeriodicStatusUpdates()
{
    if (m_statusUpdateTimer->isActive())
    {
        qDebug() << "Stopping periodic status updates";
        m_statusUpdateTimer->stop();
    }
}

// NEW: Periodic status update slot
void DeviceDiscovery::onPeriodicStatusUpdate()
{
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();

    for (int i = 0; i < m_devices.size(); ++i)
    {
        const StellarMateDevice &device = m_devices[i];
        QString ipAddress = device.ipAddress();

        // Check if we should update this device
        qint64 lastUpdate = m_lastStatusUpdate.value(ipAddress, 0);
        if (currentTime - lastUpdate >= 9500) // Allow small margin
        {
            queryDeviceStatus(ipAddress);
            m_lastStatusUpdate[ipAddress] = currentTime;
        }
    }
}

// NEW: Query device status (lightweight check)
void DeviceDiscovery::queryDeviceStatus(const QString &ipAddress)
{
    // Use hostname endpoint as a lightweight status check
    QString hostnameUrl = QString("http://%1:8624/api/info/hostname").arg(ipAddress);
    QNetworkRequest hostnameRequest{QUrl(hostnameUrl)};
    hostnameRequest.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    hostnameRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute,
                                 QNetworkRequest::NoLessSafeRedirectPolicy);

    QNetworkReply *hostnameReply = m_networkManager->get(hostnameRequest);
    hostnameReply->setProperty("ipAddress", ipAddress);
    hostnameReply->setProperty("type", "status_check");

    // Shorter timeout for status checks (5 seconds)
    QTimer::singleShot(5000, hostnameReply, [hostnameReply]()
    {
        if (hostnameReply->isRunning())
            hostnameReply->abort();
    });

    m_pendingRequests++;
    connect(hostnameReply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

int DeviceDiscovery::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return m_devices.size();
}

QVariant DeviceDiscovery::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= m_devices.size())
        return QVariant();

    const StellarMateDevice &device = m_devices.at(index.row());

    switch (role)
    {
        case Qt::DisplayRole:
            return QString("%1 (%2)").arg(device.hostname(), device.ipAddress());
        case IpAddressRole:
            return device.ipAddress();
        case HostnameRole:
            return device.hostname();
        case VersionRole:
            return device.version();
        case ModelRole:
            return device.model();
        case IsOnlineRole:
            return device.isOnline();
        case IsLocalRole:
            return device.isLocal();
        case StatusTextRole:
            return device.isLocal() ? "Local" : (device.isOnline() ? "Online" : "Offline");
        case SecondaryIpsRole:
            return device.secondaryIpAddresses();
        default:
            return QVariant();
    }
}

QHash<int, QByteArray> DeviceDiscovery::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[IpAddressRole] = "ipAddress";
    roles[HostnameRole] = "hostname";
    roles[VersionRole] = "version";
    roles[ModelRole] = "model";
    roles[IsOnlineRole] = "isOnline";
    roles[IsLocalRole] = "isLocal";
    roles[StatusTextRole] = "statusText";
    roles[SecondaryIpsRole] = "secondaryIpAddresses";
    return roles;
}

void DeviceDiscovery::startDiscovery()
{
    if (s_verbose)
        qDebug() << "Starting device discovery";

    // Mark initial device list state
    m_initialDeviceListWasEmpty = m_devices.isEmpty();

    if (m_isScanning)
    {
        stopDiscovery();
    }

    m_pendingRequests = 0;
    m_mdnsPhase = true;
    m_mdnsDevicesFound = 0;

    // Clear tracking maps
    m_deviceInfoStatus.clear();
    m_mdnsFoundIps.clear();
    m_tempDevices.clear();

    setScanning(true);
    setStatusText("Starting device discovery...");

    // Get local device info using Qt's network interface methods
    QString localHostname = QHostInfo::localHostName();

    // Find the local IP address
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    QString localIpString;

    for (const QNetworkInterface &interface : interfaces)
    {
        // Skip loopback and non-active interfaces
        if (interface.flags().testFlag(QNetworkInterface::IsLoopBack) ||
                !interface.flags().testFlag(QNetworkInterface::IsUp))
            continue;

        // Get all addresses for this interface
        QList<QNetworkAddressEntry> entries = interface.addressEntries();
        for (const QNetworkAddressEntry &entry : entries)
        {
            QHostAddress ip = entry.ip();

            // Use first valid IPv4 address that's not loopback
            if (ip.protocol() == QAbstractSocket::IPv4Protocol &&
                    !ip.isLoopback())
            {
                localIpString = ip.toString();
                break;
            }
        }

        if (!localIpString.isEmpty())
            break;
    }

    if (!localIpString.isEmpty())
    {
        if (s_verbose)
            qDebug() << "Local StellarMate detected - Network IP:" << localIpString << "Hostname:" << localHostname;

        // Query local device info
        queryDeviceInfo(localIpString);
    }

    // Start mDNS discovery
    startMdnsDiscovery();
}

void DeviceDiscovery::onMdnsServiceFound(const QString &serviceType, const QString &serviceName, const QString &host,
        const QHostAddress &address, quint16 port, const QMap<QString, QString> &txtRecords)
{
    Q_UNUSED(serviceType);
    Q_UNUSED(serviceName);
    Q_UNUSED(port);

    if (s_verbose)
        qDebug() << "mDNS service found:" << serviceName << "on host:" << host << "IP:" << address.toString() << "TXT records:" <<
                 txtRecords << "m_mdnsPhase:" << m_mdnsPhase;

    if (!m_mdnsPhase)
    {
        // We're no longer in mDNS phase, ignore
        if (s_verbose)
            qDebug() << "DEBUG: Ignoring mDNS service found as mDNS phase is over.";
        return;
    }

    QString ipAddress = address.toString();

    // Skip if we already found this IP
    if (m_mdnsFoundIps.contains(ipAddress))
    {
        if (s_verbose)
            qDebug() << "DEBUG: IP" << ipAddress << "already in m_mdnsFoundIps (from service found).";
        return;
    }

    // Check TXT records for "device record" matching "stellarmate"
    if (txtRecords.contains("device") && txtRecords.value("device").toLower() == "stellarmate")
    {
        if (s_verbose)
        {
            qDebug() << "DEBUG: Matched StellarMate TXT record for IP:" << ipAddress;
            qDebug() << "DEBUG: m_mdnsFoundIps after append:" << m_mdnsFoundIps;
        }
        m_mdnsFoundIps.append(ipAddress);
        if (s_verbose)
            qDebug() << "Found StellarMate device via mDNS service discovery:" << ipAddress << "from hostname:" << host;
        queryDeviceInfo(ipAddress);
    }
    else
    {
        if (s_verbose)
            qDebug() << "Service" << serviceName << "at" << ipAddress << "is not a StellarMate device (TXT record mismatch)";
    }
}

void DeviceDiscovery::checkForSoftwareUpdates(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= rowCount())
        return;

    QString ipAddress = data(index(deviceIndex, 0), IpAddressRole).toString();
    QUrl url(QString("http://%1:8624/api/software/upgradable?force_check=true").arg(ipAddress));
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QNetworkReply *reply = m_networkManager->get(request);
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "software_upgradable_check");

    QTimer::singleShot(30000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });

    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}
void DeviceDiscovery::applyDeltaUpdate(int deviceIndex, const QString &targetVersion)
{
    if (deviceIndex < 0 || deviceIndex >= rowCount())
        return;

    QString ipAddress = data(index(deviceIndex, 0), IpAddressRole).toString();
    QUrl url(QString("http://%1:8624/api/software/delta/apply").arg(ipAddress));
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QJsonObject payload;
    payload["target_version"] = targetVersion;
    QJsonDocument doc(payload);

    QNetworkReply *reply = m_networkManager->post(request, doc.toJson());
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "delta_apply");

    QTimer::singleShot(30000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });

    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::checkDeltaProgress(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= rowCount())
        return;

    QString ipAddress = data(index(deviceIndex, 0), IpAddressRole).toString();
    QUrl url(QString("http://%1:8624/api/software/progress").arg(ipAddress));
    QNetworkRequest request(url);

    QNetworkReply *reply = m_networkManager->get(request);
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "delta_progress");

    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::checkDeltaStatus(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= rowCount())
        return;

    QString ipAddress = data(index(deviceIndex, 0), IpAddressRole).toString();
    QUrl url(QString("http://%1:8624/api/software/delta/status").arg(ipAddress));
    QNetworkRequest request(url);

    QNetworkReply *reply = m_networkManager->get(request);
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "delta_status");

    QTimer::singleShot(10000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });

    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}


void DeviceDiscovery::startSoftwareUpdate(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= rowCount())
    {
        return;
    }
    QString ipAddress = data(index(deviceIndex, 0), IpAddressRole).toString();
    QUrl url(QString("http://%1:8624/api/software/upgrade").arg(ipAddress));
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QNetworkReply *reply = m_networkManager->get(request);
    connect(reply, &QNetworkReply::finished, this, [ = ]()
    {
        bool success = false;
        QString message;

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            qDebug() << "Raw software update start response:" << data;

            QJsonDocument doc = QJsonDocument::fromJson(data);
            if (!doc.isNull() && doc.isObject())
            {
                QJsonObject obj = doc.object();
                qDebug() << "Parsed update start JSON:" << obj;

                // API returns: {"result": true, "upgrade": "in progress"}
                if (obj.contains("result"))
                {
                    success = obj["result"].toBool(false);

                    // Check for "upgrade" status field
                    QString upgradeStatus = obj.value("upgrade").toString();
                    if (!upgradeStatus.isEmpty())
                    {
                        message = QString("Software upgrade %1").arg(upgradeStatus);
                    }
                    else
                    {
                        message = success ? "Software upgrade started successfully" : "Failed to start software upgrade";
                    }

                    qDebug() << "Upgrade started:" << success << "Status:" << upgradeStatus;
                }
                else
                {
                    success = false;
                    message = "Invalid response format from server - missing 'result' field";
                    qWarning() << message;
                }

                qDebug() << "startSoftwareUpdate:" << ipAddress << success << message;
                emit softwareUpdateStarted(ipAddress, success, message);

                if (success)
                {
                    qDebug() << "Setting up progress monitoring timer for" << ipAddress;

                    // Clean up any existing timer
                    if (softwareUpdateTimers.contains(ipAddress))
                    {
                        softwareUpdateTimers[ipAddress]->stop();
                        softwareUpdateTimers[ipAddress]->deleteLater();
                        softwareUpdateTimers.remove(ipAddress);
                    }

                    QTimer* timer = new QTimer(this);
                    softwareUpdateTimers[ipAddress] = timer;
                    connect(timer, &QTimer::timeout, this, [ = ]()
                    {
                        checkSoftwareUpdateProgress(deviceIndex);
                    });
                    timer->start(2000);  // Check every 2 seconds

                    qDebug() << "Progress monitoring started for" << ipAddress;
                }
            }
            else
            {
                success = false;
                message = "Invalid response format from server";
                qDebug() << "startSoftwareUpdate:" << ipAddress << false << message;
                emit softwareUpdateStarted(ipAddress, false, message);
            }
        }
        else
        {
            message = reply->errorString();
            qDebug() << "startSoftwareUpdate:" << ipAddress << false << message;
            emit softwareUpdateStarted(ipAddress, false, message);
        }
        reply->deleteLater();
    });
}
void DeviceDiscovery::checkSoftwareUpdateProgress(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= rowCount())
    {
        return;
    }
    QString ipAddress = data(index(deviceIndex, 0), IpAddressRole).toString();
    QUrl url(QString("http://%1:8624/api/software/progress").arg(ipAddress));
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    QNetworkReply *reply = m_networkManager->get(request);
    connect(reply, &QNetworkReply::finished, this, [ = ]()
    {
        if (reply->error() == QNetworkReply::NoError)
        {
            QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
            QJsonObject obj = doc.object();
            double progress = obj["progress"].toDouble();
            emit softwareUpdateProgressReceived(ipAddress, progress);
            if (progress >= 99.9)
            {
                if (softwareUpdateTimers.contains(ipAddress))
                {
                    softwareUpdateTimers[ipAddress]->stop();
                    softwareUpdateTimers[ipAddress]->deleteLater();
                    softwareUpdateTimers.remove(ipAddress);
                }
            }
        }
        else
        {
            if (softwareUpdateTimers.contains(ipAddress))
            {
                softwareUpdateTimers[ipAddress]->stop();
                softwareUpdateTimers[ipAddress]->deleteLater();
                softwareUpdateTimers.remove(ipAddress);
                emit softwareUpdateTimedOut(ipAddress);
            }
        }
        reply->deleteLater();
    });
}

void DeviceDiscovery::queryExternalStorage(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        qWarning() << "Invalid device index for external storage query:" << deviceIndex;
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        qWarning() << "Device IP address is empty";
        return;
    }

    if (s_verbose)
        qDebug() << "Querying external storage for device:" << ipAddress;

    // Request for external storage devices
    QString storageUrl = QString("http://%1:8624/api/info/storage").arg(ipAddress);
    QNetworkRequest request{QUrl(storageUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    QNetworkReply *reply = m_networkManager->get(request);
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "get_external_storage");
    QTimer::singleShot(10000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::openStellarMateWebUI(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        qWarning() << "Invalid device index:" << deviceIndex;
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        qWarning() << "Device IP address is empty";
        return;
    }

    // StellarMate web UI typically runs on port 80
    QString url = QString("http://%1:8624").arg(ipAddress);

    QDesktopServices::openUrl(QUrl(url));
}

void DeviceDiscovery::openCustomPort(int deviceIndex, int port)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        qWarning() << "Invalid device index:" << deviceIndex;
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        qWarning() << "Device IP address is empty";
        return;
    }

    QString url = QString("http://%1:3000").arg(ipAddress).arg(port);

    QDesktopServices::openUrl(QUrl(url));
}

void DeviceDiscovery::openVNCViewer(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        qWarning() << "Invalid device index:" << deviceIndex;
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        qWarning() << "Device IP address is empty";
        return;
    }

    // Try to open VNC viewer with the device IP
    // StellarMate typically uses VNC on port 6080
    QString vncUrl = QString("http://%1:6080").arg(ipAddress);

    // First try to open with system default VNC viewer
    if (!QDesktopServices::openUrl(QUrl(vncUrl)))
    {
        // If that fails, try some common VNC viewers
        QStringList vncCommands =
        {
            QString("vncviewer %1:6080").arg(ipAddress),
            QString("tightvncviewer %1:6080").arg(ipAddress),
            QString("krdc http://%1:6080").arg(ipAddress),
            QString("remmina -c vnc://%1:6080").arg(ipAddress)
        };

        bool success = false;
        for (const QString &command : vncCommands)
        {
            if (QProcess::startDetached(command))
            {
                success = true;
                break;
            }
        }

        if (!success)
        {
            qWarning() << "Failed to start VNC viewer. Please install a VNC client.";
            // As a fallback, try to open the VNC URL in browser (some browsers support VNC)
            QString webVncUrl = QString("http://%1:6080/vnc.html").arg(ipAddress);
            QDesktopServices::openUrl(QUrl(webVncUrl));
        }
    }
}

void DeviceDiscovery::startMdnsDiscovery()
{
    if (s_verbose)
        qDebug() << "Starting mDNS discovery phase";

    // Check if mDNS is initialized
    if (!m_mdnsInitialized)
    {
        if (s_verbose)
            qDebug() << "mDNS not yet initialized, deferring mDNS discovery start";
        m_pendingStartDiscovery = true;
        setStatusText("Initializing network discovery...");
        return;
    }

    setStatusText("Searching for StellarMate devices using mDNS...");

    // Start mDNS timeout timer
    m_mdnsTimer->start();

    // Perform mDNS service lookup for HTTP services
    // We will filter for "device=stellarmate" in the TXT records
    QString httpServiceType = "_http._tcp.local";
    if (s_verbose)
        qDebug() << "Looking up mDNS service type:" << httpServiceType;
    m_mdns->lookupService(httpServiceType);
}

void DeviceDiscovery::onMdnsHostFound(const QHostInfo &hostInfo)
{
    if (s_verbose)
        qDebug() << "mDNS host found:" << hostInfo.hostName() << "Addresses:" << hostInfo.addresses() << "m_mdnsPhase:" <<
                 m_mdnsPhase; // Added m_mdnsPhase debug

    if (!m_mdnsPhase)
    {
        // We're no longer in mDNS phase, ignore
        if (s_verbose)
            qDebug() << "DEBUG: Ignoring mDNS host found as mDNS phase is over.";
        return;
    }

    // Process each IP address found
    for (const QHostAddress &address : hostInfo.addresses())
    {
        if (address.protocol() != QAbstractSocket::IPv4Protocol)
        {
            continue; // Skip IPv6 for now
        }

        QString ipAddress = address.toString();

        // Skip if we already found this IP
        if (m_mdnsFoundIps.contains(ipAddress))
        {
            if (s_verbose)
                qDebug() << "DEBUG: IP" << ipAddress << "already in m_mdnsFoundIps (from host found).";
            continue; // Changed from return to continue to process all addresses for a host
        }

        m_mdnsFoundIps.append(ipAddress);
        if (s_verbose)
        {
            qDebug() << "DEBUG: m_mdnsFoundIps after append:" << m_mdnsFoundIps;
            qDebug() << "Found IP via mDNS:" << ipAddress << "from hostname:" << hostInfo.hostName();
            qDebug() << "Checking if" << ipAddress << "is a StellarMate device";
        }

        // Query the device to see if it's actually a StellarMate device
        queryDeviceInfo(ipAddress);
    }
}

void DeviceDiscovery::onMdnsTimeout()
{
    if (s_verbose)
        qDebug() << "mDNS discovery phase timed out. Found IPs via mDNS:" << m_mdnsFoundIps << "Pending requests:" <<
                 m_pendingRequests;

    // Wait a moment for any pending requests to complete
    QTimer::singleShot(1000, this, &DeviceDiscovery::checkMdnsCompletion);
}

void DeviceDiscovery::checkMdnsCompletion()
{
    if (!m_mdnsPhase)
    {
        return; // Already moved to next phase
    }

    // If we have pending requests for IPs found via mDNS, wait a bit longer
    bool hasPendingMdnsRequests = false;
    if (m_pendingRequests > 0)
    {
        // Check if any of the IPs for which queryDeviceInfo was initiated via mDNS are still pending completion
        for (const QString &ip : m_mdnsFoundIps)
        {
            if (m_tempDevices.contains(ip))
            {
                // Check if all three info requests (hostname, version, model, machine ID) are still pending for this IP
                std::tuple<bool, bool, bool, bool> status = m_deviceInfoStatus.value(ip, std::make_tuple(false, false, false, false));
                if (!std::get<0>(status) || !std::get<1>(status) || !std::get<2>(status))
                {
                    hasPendingMdnsRequests = true;
                    break;
                }
            }
        }
    }

    if (hasPendingMdnsRequests)
    {
        qDebug() << "Waiting for mDNS device verification to complete...";
        // Wait another 2 seconds for API responses
        QTimer::singleShot(2000, this, &DeviceDiscovery::checkMdnsCompletion);
        return;
    }

    m_mdnsPhase = false;

    if (s_verbose)
        qDebug() << "mDNS phase complete. Found" << m_mdnsDevicesFound << "StellarMate devices via mDNS";

    if (m_mdnsDevicesFound > 0)
    {
        // mDNS found devices, complete the discovery
        setStatusText(QString("mDNS discovery completed. Found %1 StellarMate device(s)").arg(m_mdnsDevicesFound));

        // Wait for any remaining pending API requests to complete
        if (m_pendingRequests == 0)
        {
            onDiscoveryTimeout(); // Complete the discovery
        }
        else
        {
            // Start the main discovery timer to ensure we don't wait forever
            m_discoveryTimer->start();
        }
    }
    else
    {
        // No devices found via mDNS, fallback to network scan
        if (m_initialDeviceListWasEmpty)
        {
            setStatusText("No devices found via mDNS, switching to deep network scan...");
            startNetworkScan();
            m_discoveryTimer->start();
        }
        else
        {
            setStatusText("No new devices found via mDNS. Skipping deep network scan as devices were present initially.");
            onDiscoveryTimeout();
        }
    }
}

void DeviceDiscovery::stopDiscovery()
{
    qInfo() << "Stopping discovery - Current pending requests:" << m_pendingRequests;

    // Stop timers
    if (m_mdnsTimer && m_mdnsTimer->isActive())
    {
        m_mdnsTimer->stop();
    }

    if (m_discoveryTimer && m_discoveryTimer->isActive())
    {
        m_discoveryTimer->stop();
    }

    // Abort all pending network requests
    QList<QNetworkReply*> activeReplies = m_networkManager->findChildren<QNetworkReply*>();
    for (QNetworkReply * reply : activeReplies)
    {
        if (reply->isRunning())
        {
            reply->disconnect();  // Disconnect signals first to prevent decrementing m_pendingRequests
            reply->abort();       // Then abort
            reply->deleteLater();
        }
    }

    // Reset state - CRITICAL to prevent negative counters
    m_pendingRequests = 0;
    m_mdnsPhase = false;

    setScanning(false);
    setStatusText("Discovery stopped");

    qInfo() << "Discovery stopped";
}

void DeviceDiscovery::addManualDevice(const QString &ipAddress)
{
    // Check if device already exists
    for (const auto &device : m_devices)
    {
        if (device.ipAddress() == ipAddress)
        {
            setStatusText(QString("Device %1 already exists").arg(ipAddress));
            return;
        }
    }

    setStatusText(QString("Adding device %1...").arg(ipAddress));
    queryDeviceInfo(ipAddress);
}

void DeviceDiscovery::removeDevice(int index)
{
    if (index < 0 || index >= m_devices.size())
        return;

    const StellarMateDevice &device = m_devices.at(index);

    // Prevent removal of local devices
    if (device.isLocal())
    {
        setStatusText("Cannot remove local device");
        return;
    }

    QString ipAddress = device.ipAddress();

    beginRemoveRows(QModelIndex(), index, index);
    m_devices.removeAt(index);
    endRemoveRows();

    emit deviceCountChanged();
    emit deviceRemoved(ipAddress);
    setStatusText(QString("Device %1 removed").arg(ipAddress));
}

void DeviceDiscovery::refreshDevice(int index)
{
    if (index < 0 || index >= m_devices.size())
        return;

    const QString ipAddress = m_devices.at(index).ipAddress();

    if (m_activeRefreshes.contains(ipAddress))
    {
        RefreshOperation &op = m_activeRefreshes[ipAddress];
        if (op.timeoutTimer)
        {
            op.timeoutTimer->stop();
            op.timeoutTimer->deleteLater();
        }
        m_activeRefreshes.remove(ipAddress);
    }

    setStatusText(QString("Refreshing device %1...").arg(ipAddress));

    RefreshOperation refreshOp;
    refreshOp.hostnameReceived = 0;
    refreshOp.versionReceived = 0;
    refreshOp.modelReceived = 0;

    refreshOp.timeoutTimer = new QTimer(this);
    refreshOp.timeoutTimer->setSingleShot(true);

    connect(refreshOp.timeoutTimer, &QTimer::timeout, this, [this, ipAddress]()
    {
        if (s_verbose)
            qWarning() << "Refresh operation timed out for" << ipAddress;
        setStatusText(QString("Refresh timed out for device %1").arg(ipAddress));

        if (m_activeRefreshes.contains(ipAddress))
        {
            RefreshOperation &op = m_activeRefreshes[ipAddress];
            if (op.timeoutTimer)
            {
                op.timeoutTimer->deleteLater();
            }
            m_activeRefreshes.remove(ipAddress);
        }
    });

    m_activeRefreshes[ipAddress] = refreshOp;

    m_activeRefreshes[ipAddress].timeoutTimer->start(15000);

    queryDeviceInfo(ipAddress);
}

void DeviceDiscovery::checkRefreshCompletion(const QString &ipAddress)
{
    // Only check if we have an active refresh for this IP
    if (!m_activeRefreshes.contains(ipAddress))
    {
        if (s_verbose)
            qDebug() << "No active refresh for" << ipAddress;
        return;
    }

    RefreshOperation &op = m_activeRefreshes[ipAddress];

    if (s_verbose)
    {
        qDebug() << "Checking refresh completion for" << ipAddress
                 << "- hostname:" << op.hostnameReceived
                 << "version:" << op.versionReceived
                 << "model:" << op.modelReceived;
    }

    if (op.hostnameReceived != 0 && op.versionReceived != 0 && op.modelReceived != 0)
    {
        int successCount = 0;
        if (op.hostnameReceived == 1) successCount++;
        if (op.versionReceived == 1) successCount++;
        if (op.modelReceived == 1) successCount++;

        if (successCount == 3)
        {
            setStatusText(QString("Device %1 refreshed successfully").arg(ipAddress));
        }
        else if (successCount > 0)
        {
            setStatusText(QString("Device %1 partially refreshed (%2/3 requests succeeded)").arg(ipAddress).arg(successCount));
        }
        else
        {
            setStatusText(QString("Failed to refresh device %1").arg(ipAddress));
        }

        if (s_verbose)
            qDebug() << "Refresh completed for" << ipAddress << "- success count:" << successCount;

        if (op.timeoutTimer)
        {
            op.timeoutTimer->stop();
            op.timeoutTimer->deleteLater();
        }
        m_activeRefreshes.remove(ipAddress);
    }
}
void DeviceDiscovery::refreshAllDevices()
{
    setStatusText("Refreshing all devices...");
    for (const auto &device : m_devices)
    {
        queryDeviceInfo(device.ipAddress());
    }
}

void DeviceDiscovery::queryDeviceInfo(const QString &ipAddress)
{
    // Request for hostname
    QString hostnameUrl = QString("http://%1:8624/api/info/hostname").arg(ipAddress);
    QNetworkRequest hostnameRequest{QUrl(hostnameUrl)};
    hostnameRequest.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    hostnameRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    QNetworkReply *hostnameReply = m_networkManager->get(hostnameRequest);
    hostnameReply->setProperty("ipAddress", ipAddress);
    hostnameReply->setProperty("type", "hostname");
    QTimer::singleShot(10000, hostnameReply, [hostnameReply]() // Increased timeout to 10 seconds
    {
        if (hostnameReply->isRunning()) hostnameReply->abort();
    });
    m_pendingRequests++;
    connect(hostnameReply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);

    // Request for version
    QString versionUrl = QString("http://%1:8624/api/info/version").arg(ipAddress);
    QNetworkRequest versionRequest{QUrl(versionUrl)};
    versionRequest.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    versionRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    QNetworkReply *versionReply = m_networkManager->get(versionRequest);
    versionReply->setProperty("ipAddress", ipAddress);
    versionReply->setProperty("type", "version");
    QTimer::singleShot(10000, versionReply, [versionReply]() // Increased timeout to 10 seconds
    {
        if (versionReply->isRunning()) versionReply->abort();
    });
    m_pendingRequests++;
    connect(versionReply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);

    // Request for model
    QString modelUrl = QString("http://%1:8624/api/info/model").arg(ipAddress);
    QNetworkRequest modelRequest{QUrl(modelUrl)};
    modelRequest.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    modelRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    QNetworkReply *modelReply = m_networkManager->get(modelRequest);
    modelReply->setProperty("ipAddress", ipAddress);
    modelReply->setProperty("type", "model");
    QTimer::singleShot(10000, modelReply, [modelReply]() // Increased timeout to 10 seconds
    {
        if (modelReply->isRunning()) modelReply->abort();
    });

    QString machineIdUrl = QString("http://%1:8624/api/info/machine-id").arg(ipAddress);
    QNetworkRequest machineIdRequest{QUrl(machineIdUrl)};
    machineIdRequest.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    machineIdRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute,
                                  QNetworkRequest::NoLessSafeRedirectPolicy);

    QNetworkReply *machineIdReply = m_networkManager->get(machineIdRequest);
    machineIdReply->setProperty("ipAddress", ipAddress);
    machineIdReply->setProperty("type", "machine_id");
    QTimer::singleShot(10000, machineIdReply, [machineIdReply]()
    {
        if (machineIdReply->isRunning()) machineIdReply->abort();
    });
    m_pendingRequests++;
    connect(machineIdReply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
    connect(modelReply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::queryPicturesDirectory(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        qWarning() << "Invalid device index for pictures directory query:" << deviceIndex;
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        qWarning() << "Device IP address is empty";
        return;
    }

    // Request for pictures directory
    QString picturesUrl = QString("http://%1:8624/api/info/pictures").arg(ipAddress);
    QNetworkRequest picturesRequest{QUrl(picturesUrl)};
    picturesRequest.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    picturesRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    QNetworkReply *picturesReply = m_networkManager->get(picturesRequest);
    picturesReply->setProperty("ipAddress", ipAddress);
    picturesReply->setProperty("type", "get_pictures_directory");
    QTimer::singleShot(10000, picturesReply, [picturesReply]()
    {
        if (picturesReply->isRunning()) picturesReply->abort();
    });
    m_pendingRequests++;
    connect(picturesReply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);

    qInfo() << "Querying pictures directory for device:" << ipAddress;
}

void DeviceDiscovery::updatePicturesDirectory(int deviceIndex, const QString &newDirectory)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        emit picturesDirectoryUpdated("", false, "Invalid device index");
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        emit picturesDirectoryUpdated(ipAddress, false, "Device IP address is empty");
        return;
    }

    // Validate directory path
    QString finalDirectory = newDirectory.simplified();
    if (finalDirectory.isEmpty())
    {
        emit picturesDirectoryUpdated(ipAddress, false, "Directory path cannot be empty");
        return;
    }

    setStatusText(QString("Updating pictures directory for %1 to %2...").arg(ipAddress, finalDirectory));

    // Create JSON payload
    QJsonObject payload;
    payload["directory"] = finalDirectory;
    QJsonDocument doc(payload);
    QByteArray jsonData = doc.toJson();

    QString picturesUrl = QString("http://%1:8624/api/info/pictures").arg(ipAddress);
    QNetworkRequest request{QUrl(picturesUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setRawHeader("Content-Type", "application/json");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    if (s_verbose)
    {
        qDebug() << "Making pictures directory update request to:" << picturesUrl;
        qDebug() << "JSON payload:" << jsonData;
    }

    QNetworkReply *reply = m_networkManager->post(request, jsonData);
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "update_pictures_directory");
    reply->setProperty("newDirectory", finalDirectory);
    QTimer::singleShot(10000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::networkReset(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        emit networkResetCompleted("", false, "Invalid device index");
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        emit networkResetCompleted(ipAddress, false, "Device IP address is empty");
        return;
    }

    setStatusText(QString("Performing network reset for device %1...").arg(ipAddress));

    QString networkResetUrl = QString("http://%1:8624/api/system/network_reset").arg(ipAddress);
    QNetworkRequest request{QUrl(networkResetUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setRawHeader("Content-Type", "application/json");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    if (s_verbose)
        qDebug() << "Making network reset request to:" << networkResetUrl;

    // Empty POST request
    QNetworkReply *reply = m_networkManager->post(request, QByteArray());
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "network_reset");
    QTimer::singleShot(15000, reply, [reply]() // Longer timeout for system operations
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::resetEkosLive(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        emit ekosLiveResetCompleted("", false, "Invalid device index");
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        emit ekosLiveResetCompleted(ipAddress, false, "Device IP address is empty");
        return;
    }

    setStatusText(QString("Initiating EkosLive reset for device %1...").arg(ipAddress));

    // Phase 0: Call the initial reset API
    const QString url = QString("http://%1:3000/reset").arg(ipAddress);
    QNetworkRequest request{QUrl(url)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setRawHeader("Content-Type", "application/json");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    if (s_verbose)
        qDebug() << "Making initial EkosLive reset request to:" << url;

    // Assuming /reset is a POST endpoint based on typical reset operations
    QNetworkReply *reply = m_networkManager->get(request, QByteArray()); // Empty POST body
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "ekoslive_reset_phase0");
    QTimer::singleShot(15000, reply, [reply]() // Longer timeout for service operations
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::reboot(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        emit rebootCompleted("", false, "Invalid device index");
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        emit rebootCompleted(ipAddress, false, "Device IP address is empty");
        return;
    }

    setStatusText(QString("Rebooting device %1...").arg(ipAddress));

    QString rebootUrl = QString("http://%1:8624/api/system/reboot").arg(ipAddress);
    QNetworkRequest request{QUrl(rebootUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setRawHeader("Content-Type", "application/json");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    if (s_verbose)
        qDebug() << "Making reboot request to:" << rebootUrl;

    // Empty POST request
    QNetworkReply *reply = m_networkManager->post(request, QByteArray());
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "reboot");
    QTimer::singleShot(15000, reply, [reply]() // Longer timeout for system operations
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);

    for (int i = 0; i < m_devices.size(); ++i)
    {
        if (m_devices[i].ipAddress() == ipAddress)
        {
            m_devices[i].setIsOnline(false);
            QModelIndex modelIndex = createIndex(i, 0);
            emit dataChanged(modelIndex, modelIndex, QVector<int>() << IsOnlineRole << StatusTextRole);
            break;
        }
    }
}

void DeviceDiscovery::shutdown(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        emit shutdownCompleted("", false, "Invalid device index");
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        emit shutdownCompleted(ipAddress, false, "Device IP address is empty");
        return;
    }

    setStatusText(QString("Shutting down device %1...").arg(ipAddress));

    QString shutdownUrl = QString("http://%1:8624/api/system/shutdown").arg(ipAddress);
    QNetworkRequest request{QUrl(shutdownUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setRawHeader("Content-Type", "application/json");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    if (s_verbose)
        qDebug() << "Making shutdown request to:" << shutdownUrl;

    // Empty POST request
    QNetworkReply *reply = m_networkManager->post(request, QByteArray());
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "shutdown");
    QTimer::singleShot(15000, reply, [reply]() // Longer timeout for system operations
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::setUseInternalWifi(bool useInternal)
{
    if (m_useInternalWifi != useInternal)
    {
        m_useInternalWifi = useInternal;
        emit hotspotInterfaceChanged();
    }
}

void DeviceDiscovery::queryHotspotInterface(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        qWarning() << "Invalid device index for hotspot interface query:" << deviceIndex;
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        qWarning() << "Device IP address is empty";
        return;
    }

    if (s_verbose)
        qDebug() << "Querying hotspot interface for device:" << ipAddress;

    // Request for hotspot interface setting using the corresponding GET endpoint
    QString hotspotUrl = QString("http://%1:8624/api/system/hotspot_interface").arg(ipAddress);
    QNetworkRequest request{QUrl(hotspotUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    QNetworkReply *reply = m_networkManager->get(request);
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "get_hotspot_interface");
    QTimer::singleShot(10000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::updateHotspotInterface(int deviceIndex, bool useInternalWifi)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        emit hotspotInterfaceUpdated("", false, "Invalid device index");
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        emit hotspotInterfaceUpdated(ipAddress, false, "Device IP address is empty");
        return;
    }

    setStatusText(QString("Updating hotspot interface for %1...").arg(ipAddress));

    // Use the actual API endpoint: POST /api/system/hotspot_interface/{name}
    QString interfaceName = useInternalWifi ? "wlan0" : "wlan1";
    QString hotspotUrl = QString("http://%1:8624/api/system/hotspot_interface/%2").arg(ipAddress, interfaceName);
    QNetworkRequest request{QUrl(hotspotUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    if (s_verbose)
    {
        qDebug() << "Making hotspot interface update request to:" << hotspotUrl;
        qDebug() << "Interface name:" << interfaceName;
    }

    // POST with empty body to the parameterized endpoint
    QNetworkReply *reply = m_networkManager->post(request, QByteArray());
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "update_hotspot_interface");
    reply->setProperty("useInternalWifi", useInternalWifi);
    reply->setProperty("interfaceName", interfaceName);
    QTimer::singleShot(10000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::queryNetworkInterfaces(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        qWarning() << "Invalid device index for network interfaces query:" << deviceIndex;
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        qWarning() << "Device IP address is empty";
        return;
    }

    if (s_verbose)
        qDebug() << "Querying network interfaces for device:" << ipAddress;

    // Request for network interfaces
    QString interfacesUrl = QString("http://%1:8624/api/info/all_interfaces").arg(ipAddress);
    QNetworkRequest request{QUrl(interfacesUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    QNetworkReply *reply = m_networkManager->get(request);
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "get_network_interfaces");
    QTimer::singleShot(10000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

// ADD this method implementation:
void DeviceDiscovery::triggerEkosLiveImageRegeneration(const QString &ipAddress)
{
    setStatusText(QString("Triggering EkosLive image regeneration for device %1...").arg(ipAddress));

    QString imageRegenUrl = QString("http://%1:3000/generate").arg(ipAddress);
    QNetworkRequest request{QUrl(imageRegenUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    if (s_verbose)
        qDebug() << "Making EkosLive image regeneration request to:" << imageRegenUrl;

    QNetworkReply *reply = m_networkManager->get(request);
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "ekoslive_reset_phase2");
    QTimer::singleShot(30000, reply, [reply]() // Longer timeout for image generation
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::checkEkosLiveRegenerationProgress(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
        return;

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
        return;

    QString progressUrl = QString("http://%1:3000/generate/progress").arg(ipAddress);
    QNetworkRequest request{QUrl(progressUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    if (s_verbose)
        qDebug() << "Checking EkosLive regeneration progress for:" << ipAddress;

    QNetworkReply *reply = m_networkManager->get(request);
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "ekoslive_regeneration_progress");
    reply->setProperty("deviceIndex", deviceIndex);
    QTimer::singleShot(10000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::factoryReset(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        emit factoryResetCompleted("", false, "Invalid device index");
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        emit factoryResetCompleted(ipAddress, false, "Device IP address is empty");
        return;
    }

    setStatusText(QString("Performing factory reset for device %1...").arg(ipAddress));

    QString factoryResetUrl = QString("http://%1:8624/api/system/factory_reset").arg(ipAddress);
    QNetworkRequest request{QUrl(factoryResetUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setRawHeader("Content-Type", "application/json");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    if (s_verbose)
        qDebug() << "Making factory reset request to:" << factoryResetUrl;

    // Empty POST request
    QNetworkReply *reply = m_networkManager->post(request, QByteArray());
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "factory_reset");
    QTimer::singleShot(20000, reply, [reply]() // Longer timeout for factory reset
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

/**
 * Apply rollback to a specific version
 * API: POST /api/software/delta/rollback
 * Body: {"target_version": "2.0.0"}
 * Response: {"result": true, "message": "Rollback to 2.0.0 prepared. Please reboot.", "payload": null}
 */
void DeviceDiscovery::applyRollback(int deviceIndex, const QString &targetVersion)
{
    if (deviceIndex < 0 || deviceIndex >= rowCount())
    {
        emit rollbackApplyCompleted("", false, "Invalid device index");
        return;
    }

    QString ipAddress = data(index(deviceIndex, 0), IpAddressRole).toString();

    if (targetVersion.isEmpty())
    {
        emit rollbackApplyCompleted(ipAddress, false, "Target version not specified");
        return;
    }

    qInfo() << "Applying rollback to version" << targetVersion << "for device" << ipAddress;

    // API endpoint for rollback
    QUrl url(QString("http://%1:8624/api/software/delta/rollback").arg(ipAddress));
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setRawHeader("accept", "application/json");

    // Create JSON payload: {"target_version": "2.0.0"}
    QJsonObject payload;
    payload["target_version"] = targetVersion;
    QJsonDocument doc(payload);

    if (s_verbose)
    {
        qDebug() << "Rollback request URL:" << url.toString();
        qDebug() << "Rollback request payload:" << doc.toJson();
    }

    QNetworkReply *reply = m_networkManager->post(request, doc.toJson());
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "rollback_apply");
    reply->setProperty("targetVersion", targetVersion);

    // 30 second timeout for rollback operation
    QTimer::singleShot(30000, reply, [reply]()
    {
        if (reply->isRunning())
        {
            qWarning() << "Rollback request timed out";
            reply->abort();
        }
    });

    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}


void DeviceDiscovery::onNetworkReplyFinished()
{
    QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
    if (!reply)
        return;

    QString ipAddress = reply->property("ipAddress").toString();
    QString type = reply->property("type").toString();
    if (m_pendingRequests > 0)
    {
        m_pendingRequests--;
    }

    if (type == "software_upgradable_check")
    {
        bool success = false;
        bool isUpgradable = false;
        bool hasDelta = false;
        QString message;
        QVariantMap deltaMetadata;

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            QJsonDocument doc = QJsonDocument::fromJson(data);
            QJsonObject obj = doc.object();

            if (s_verbose)
                qDebug() << "Software upgradable check response:" << obj;

            if (obj["result"].toBool() && obj.contains("payload"))
            {
                QJsonObject payload = obj["payload"].toObject();
                success = true;
                isUpgradable = payload["upgradable"].toBool(false);

                // Check for delta_metadata
                if (payload.contains("delta_metadata") && payload["delta_metadata"].isObject())
                {
                    QJsonObject delta = payload["delta_metadata"].toObject();

                    if (delta["available"].toBool(false))
                    {
                        hasDelta = true;
                        deltaMetadata["available"] = true;
                        deltaMetadata["current_version"] = delta["current_version"].toString();
                        deltaMetadata["target_version"] = delta["target_version"].toString();
                        deltaMetadata["size_mb"] = delta["size_mb"].toDouble();
                        deltaMetadata["release_title"] = delta["release_title"].toString();
                        deltaMetadata["release_date"] = delta["release_date"].toString();

                        // Convert changelog array
                        QStringList changelog;
                        for (const auto &item : delta["changelog"].toArray())
                            changelog.append(item.toString());
                        deltaMetadata["changelog"] = changelog;

                        message = "Delta update available";
                        if (s_verbose)
                            qDebug() << "Delta update available:" << deltaMetadata;
                    }
                }

                if (!hasDelta)
                {
                    message = isUpgradable ? "Software update available" : "Software is up to date";
                }
            }
            else
            {
                success = false;
                message = "Invalid API response format";
            }
        }
        else
        {
            message = reply->errorString();
            qCritical() << "Software update check failed:" << message;
        }

        emit softwareUpdateCheckCompleted(ipAddress, success, isUpgradable, message, hasDelta, deltaMetadata);
        reply->deleteLater();
        return;
    }
    if (type == "delta_apply")
    {
        bool success = false;
        QString message;
        QString ipAddress = reply->property("ipAddress").toString();

        if (s_verbose)
            qDebug() << "Delta apply response - HTTP status:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            qDebug() << "Raw delta apply response:" << data;

            QJsonDocument doc = QJsonDocument::fromJson(data);
            QJsonObject obj = doc.object();

            success = obj["result"].toBool(false);

            // Get message from response
            if (obj.contains("message") && !obj["message"].isNull())
            {
                message = obj["message"].toString();
            }
            else if (obj.contains("error"))
            {
                message = obj["error"].toString();
            }
            else if (obj.contains("payload") && obj["payload"].isObject())
            {
                QJsonObject payload = obj["payload"].toObject();
                if (payload.contains("message"))
                    message = payload["message"].toString();
                if (payload.contains("error"))
                    message = payload["error"].toString();
            }

            if (message.isEmpty())
            {
                message = success ? "Delta update started" : "Failed to start delta update (no error details)";
            }

            if (s_verbose)
                qDebug() << "Delta apply - success:" << success << "message:" << message;
        }
        else
        {
            message = QString("Network error: %1").arg(reply->errorString());
            qCritical() << "Delta apply network error:" << message;
        }

        emit deltaUpdateStarted(ipAddress, success, message);
        reply->deleteLater();
        return;
    }

    if (type == "update_hotspot_interface")
    {
        bool success = false;
        QString message;
        QString ipAddress = reply->property("ipAddress").toString();

        if (s_verbose)
            qDebug() << "Hotspot interface update response - HTTP status:" << reply->attribute(
                         QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw hotspot interface update response:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();
                // API might return "result": true OR "success": "message"
                bool result = obj.value("result").toBool(false);
                if (!result && obj.contains("success"))
                {
                    result = true;
                }

                if (result)
                {
                    success = true;
                    message = "Hotspot interface updated successfully. Verifying...";
                    qInfo() << message;

                    // Verify the change by querying the interface
                    for (int i = 0; i < m_devices.size(); ++i)
                    {
                        if (m_devices[i].ipAddress() == ipAddress)
                        {
                            queryHotspotInterface(i);
                            queryNetworkInterfaces(i);
                            break;
                        }
                    }
                }
                else
                {
                    message = "Failed to update hotspot interface";
                    qCritical() << message;
                }
            }
            else
            {
                message = "Invalid response from server";
                qWarning() << message;
            }
        }
        else
        {
            message = QString("Network error: %1").arg(reply->errorString());
            qCritical() << message;
        }

        emit hotspotInterfaceUpdated(ipAddress, success, message);
        reply->deleteLater();
        return;
    }

    if (type == "get_hotspot_interface")
    {
        bool success = false;
        bool useInternalWifi = true;

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw hotspot interface response data:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();
                bool result = obj.value("result").toBool(false);

                if (result && obj.contains("payload"))
                {
                    QJsonObject payload = obj.value("payload").toObject();
                    QString interface = payload.value("interface").toString();

                    // wlan0 = internal wifi, wlan1 = external dongle
                    useInternalWifi = (interface == "wlan0");

                    if (s_verbose)
                        qDebug() << "Hotspot interface:" << interface << "useInternalWifi:" << useInternalWifi;
                    success = true;
                }
            }
            else
            {
                qCritical() << "Failed to parse hotspot interface response:" << error.errorString();
            }
        }
        else
        {
            qCritical() << "Network error getting hotspot interface:" << reply->errorString();
        }

        // hasDongle should be determined from network interfaces (wlan1 presence)
        // For now, emit the signal - QML will set hasDongle from networkInterfacesReceived
        emit hotspotInterfaceReceived(ipAddress, useInternalWifi);
        reply->deleteLater();
        return;
    }

    if (type == "rollback_apply")
    {
        bool success = false;
        QString message;
        QString ipAddress = reply->property("ipAddress").toString();
        QString targetVersion = reply->property("targetVersion").toString();

        if (s_verbose)
            qDebug() << "Rollback apply response - HTTP status:"
                     << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw rollback apply response:" << data;

            QJsonDocument doc = QJsonDocument::fromJson(data);
            if (!doc.isNull() && doc.isObject())
            {
                QJsonObject obj = doc.object();

                // Expected response: {"result": true, "message": "Rollback to 2.0.0 prepared. Please reboot.", "payload": null}
                success = obj["result"].toBool(false);
                message = obj["message"].toString();

                if (success)
                {
                    qInfo() << "Rollback prepared successfully:" << message;

                    // If no message provided, create a default one
                    if (message.isEmpty())
                    {
                        message = QString("Rollback to %1 prepared. Please reboot.").arg(targetVersion);
                    }
                }
                else
                {
                    if (message.isEmpty())
                    {
                        message = "Failed to prepare rollback";
                    }
                    qCritical() << "Rollback failed:" << message;
                }
            }
            else
            {
                message = "Invalid response from server";
                qCritical() << "Rollback apply: Invalid JSON response";
            }
        }
        else
        {
            message = QString("Network error: %1").arg(reply->errorString());
            qCritical() << "Rollback apply network error:" << message;

            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            if (httpStatus != 0)
            {
                message += QString(" (HTTP %1)").arg(httpStatus);
            }
        }

        emit rollbackApplyCompleted(ipAddress, success, message);
        reply->deleteLater();
        return;
    }

    if (type == "status_check")
    {
        int index = -1;
        for (int i = 0; i < m_devices.size(); ++i)
        {
            if (m_devices[i].ipAddress() == ipAddress)
            {
                index = i;
                break;
            }
        }
        if (index == -1)
        {
            reply->deleteLater();
            return;
        }

        bool wasOffline = !m_devices[index].isOnline();  // Track previous state
        bool online = false;
        QString newHostname;

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            QJsonDocument doc = QJsonDocument::fromJson(data);
            if (!doc.isNull() && doc.isObject())
            {
                QJsonObject obj = doc.object();
                newHostname = obj.value("hostname").toString();
                if (!newHostname.isEmpty() && newHostname != "Unknown" && newHostname != "N/A")
                {
                    online = true;
                }
            }
        }

        StellarMateDevice &device = m_devices[index];
        bool statusChanged = (device.isOnline() != online);

        if (statusChanged)
        {
            device.setIsOnline(online);
            emit dataChanged(createIndex(index, 0), createIndex(index, 0), QVector<int>() << IsOnlineRole << StatusTextRole);

            // If device came back online after being offline, refresh ALL device info
            // This ensures version, model, hostname are all updated after reboot
            if (online && wasOffline)
            {
                qInfo() << "Device" << ipAddress << "came back online after being offline - refreshing full device info";
                queryDeviceInfo(ipAddress);  // This will update version, model, hostname
            }
        }

        // Optionally update hostname if changed
        if (online && !newHostname.isEmpty() && device.hostname() != newHostname)
        {
            device.setHostname(newHostname);
            emit dataChanged(createIndex(index, 0), createIndex(index, 0), QVector<int>() << HostnameRole);
        }

        reply->deleteLater();
        return;
    }

    if (type == "delta_progress")
    {
        int progress = 0;
        QString message;

        if (reply->error() == QNetworkReply::NoError)
        {
            QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
            QJsonObject obj = doc.object();
            progress = qRound(obj["progress"].toDouble(0));

            if (obj.contains("payload") && obj["payload"].isObject())
            {
                message = obj["payload"].toObject()["message"].toString();
            }
        }

        emit deltaUpdateProgressReceived(ipAddress, progress, message);
        reply->deleteLater();
        return;
    }

    if (type == "delta_status")
    {
        bool pendingReboot = false;
        QString state;

        if (reply->error() == QNetworkReply::NoError)
        {
            QJsonDocument doc = QJsonDocument::fromJson(reply->readAll());
            QJsonObject obj = doc.object();

            if (obj["result"].toBool() && obj.contains("payload"))
            {
                QJsonObject payload = obj["payload"].toObject();
                pendingReboot = payload["pending_reboot"].toBool(false);
                state = payload["state"].toString();
            }
        }

        emit deltaStatusReceived(ipAddress, pendingReboot, state);
        reply->deleteLater();
        return;
    }

    if (type == "get_external_storage")
    {
        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw external storage response data:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();
                bool result = obj.value("result").toBool(false);

                if (result && obj.contains("payload"))
                {
                    QJsonArray payloadArray = obj.value("payload").toArray();
                    QStringList externalDevices;

                    for (const auto &deviceValue : payloadArray)
                    {
                        QJsonArray deviceArray = deviceValue.toArray();

                        // Each device is an array: [device_path, mount_point, filesystem, options]
                        if (deviceArray.size() >= 2)
                        {
                            QString mountPoint = deviceArray[1].toString();

                            // Only include devices mounted under /media/stellarmate
                            if (mountPoint.startsWith("/media/stellarmate") || mountPoint.startsWith("/run/media"))
                            {
                                externalDevices.append(mountPoint);
                                qInfo() << "Found external storage device:" << mountPoint;
                            }
                        }
                    }

                    if (s_verbose)
                        qDebug() << "Emitting externalStorageReceived for" << ipAddress << "with" << externalDevices.size() << "devices";
                    emit externalStorageReceived(ipAddress, externalDevices);
                }
                else
                {
                    qWarning() << "Failed to get external storage for" << ipAddress << ": Server returned result=false";
                    emit externalStorageReceived(ipAddress, QStringList());
                }
            }
            else
            {
                qCritical() << "Failed to parse external storage response for" << ipAddress << ":" << error.errorString();
                emit externalStorageReceived(ipAddress, QStringList());
            }
        }
        else
        {
            qDebug() << "Network error getting external storage for" << ipAddress << ":" << reply->errorString();
            emit externalStorageReceived(ipAddress, QStringList());
        }
        reply->deleteLater();
        return;
    }

    if (type == "get_network_interfaces")
    {
        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw network interfaces response data:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError)
            {
                QVariantMap interfacesMap;
                QVariantList interfacesList;
                bool success = false;

                if (doc.isArray())
                {
                    // Old style: direct array of interfaces
                    QJsonArray interfacesArray = doc.array();
                    for (const auto &interfaceValue : interfacesArray)
                    {
                        QJsonObject interfaceObj = interfaceValue.toObject();
                        QVariantMap interfaceMap;
                        interfaceMap["interface"] = interfaceObj.value("interface").toString();
                        interfaceMap["ip"] = interfaceObj.value("ip").toString();
                        interfacesList.append(interfaceMap);
                    }
                    success = true;
                    if (s_verbose)
                        qDebug() << "Parsed old-style network interfaces response for" << ipAddress;
                }
                else if (doc.isObject())
                {
                    QJsonObject obj = doc.object();
                    success = obj.value("result").toBool(false);

                    if (success && obj.contains("interfaces"))
                    {
                        QJsonArray interfacesArray = obj.value("interfaces").toArray();
                        for (const auto &interfaceValue : interfacesArray)
                        {
                            QJsonObject interfaceObj = interfaceValue.toObject();
                            QVariantMap interfaceMap;
                            interfaceMap["interface"] = interfaceObj.value("interface").toString();
                            interfaceMap["ip"] = interfaceObj.value("ip").toString();
                            interfacesList.append(interfaceMap);
                        }
                        if (s_verbose)
                            qDebug() << "Parsed new-style network interfaces response for" << ipAddress;
                    }
                    else
                    {
                        qCritical() << "Failed to get network interfaces for" << ipAddress <<
                                       ": Server returned result=false or missing interfaces array";
                    }
                }
                else
                {
                    qCritical() << "Failed to parse network interfaces response for" << ipAddress << ": Neither array nor object";
                }

                interfacesMap["result"] = success;
                interfacesMap["interfaces"] = interfacesList;

                // Update the device's secondary IPs based on network interfaces
                if (success)
                {
                    for (int i = 0; i < m_devices.size(); ++i)
                    {
                        if (m_devices[i].ipAddress() == ipAddress)
                        {
                            // Clear existing secondary IPs and rebuild from interfaces
                            QStringList newSecondaryIps;
                            QString primaryIp = m_devices[i].ipAddress();
                            
                            for (const auto &interfaceValue : interfacesList)
                            {
                                QVariantMap interfaceMap = interfaceValue.toMap();
                                QString ip = interfaceMap["ip"].toString();
                                QString ifaceName = interfaceMap["interface"].toString();
                                
                                // Add valid IPs that are not the primary IP and not empty
                                if (!ip.isEmpty() && ip != "0.0.0.0" && ip != primaryIp)
                                {
                                    if (!newSecondaryIps.contains(ip))
                                    {
                                        newSecondaryIps.append(ip);
                                        if (s_verbose)
                                            qDebug() << "Adding secondary IP" << ip << "from interface" << ifaceName << "to device" << ipAddress;
                                    }
                                }
                            }
                            
                            // Update the device's secondary IPs
                            m_devices[i].setSecondaryIpAddresses(newSecondaryIps);
                            
                            // Emit dataChanged to notify the UI
                            QModelIndex modelIndex = createIndex(i, 0);
                            emit dataChanged(modelIndex, modelIndex, QVector<int>() << SecondaryIpsRole);
                            
                            if (s_verbose)
                                qDebug() << "Updated secondary IPs for device" << ipAddress << ":" << newSecondaryIps;
                            break;
                        }
                    }
                }

                emit networkInterfacesReceived(ipAddress, interfacesMap);
            }
            else
            {
                qCritical() << "Failed to parse network interfaces response for" << ipAddress << ":" << error.errorString();
                QVariantMap emptyMap;
                emptyMap["result"] = false;
                emptyMap["interfaces"] = QVariantList();
                emit networkInterfacesReceived(ipAddress, emptyMap);
            }
        }
        else
        {
            qCritical() << "Network error getting network interfaces for" << ipAddress << ":" << reply->errorString();
            QVariantMap emptyMap;
            emptyMap["result"] = false;
            emptyMap["interfaces"] = QVariantList();
            emit networkInterfacesReceived(ipAddress, emptyMap);
        }
        reply->deleteLater();
        return;
    }
    if (type == "factory_reset")
    {
        bool success = false;
        QString message;
        QString ipAddress = reply->property("ipAddress").toString();

        if (s_verbose)
        {
            qDebug() << "Factory reset response - HTTP status:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            qDebug() << "Factory reset response - Network error:" << reply->error();
        }

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw factory reset response data:" << data;

            if (data.isEmpty())
            {
                // Empty response might be normal for factory reset
                success = true;
                message = QString("Factory reset successfully initiated for device %1. All settings have been restored to defaults.").arg(
                              ipAddress);
                qInfo() << message;
            }
            else
            {
                // Try to parse JSON if we got data
                QJsonParseError error;
                QJsonDocument doc = QJsonDocument::fromJson(data, &error);

                if (error.error == QJsonParseError::NoError && doc.isObject())
                {
                    QJsonObject obj = doc.object();

                    // Check for success field
                    if (obj.contains("success") && !obj.value("success").toString().isEmpty())
                    {
                        success = true;
                        QString successMessage = obj.value("success").toString();
                        message = QString("Factory reset successful for device %1: %2").arg(ipAddress, successMessage);
                        qInfo() << message;
                    }
                    else if (obj.contains("result") && obj.value("result").toBool(false))
                    {
                        success = true;
                        message = QString("Factory reset successfully initiated for device %1. All settings have been restored to defaults.").arg(
                                      ipAddress);
                        qInfo() << message;
                    }
                    else
                    {
                        success = false;
                        message = QString("Factory reset failed for %1: Server returned result=false").arg(ipAddress);
                        qCritical() << message;
                    }
                }
                else
                {
                    success = false;
                    message = QString("Factory reset failed for %1: Invalid JSON response - %2").arg(ipAddress, error.errorString());
                    qCritical() << message << "Raw data:" << data;
                }
            }
        }
        else
        {
            success = false;
            message = QString("Factory reset failed for %1: Network error - %2").arg(ipAddress, reply->errorString());
            qCritical() << message;

            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            if (httpStatus != 0)
            {
                message += QString(" (HTTP %1)").arg(httpStatus);
            }
        }

        emit factoryResetCompleted(ipAddress, success, message);
        setStatusText(message);
        reply->deleteLater();
        return;
    }

    if (type == "ekoslive_reset_phase0")
    {
        bool success = false;
        QString message;
        QString ipAddress = reply->property("ipAddress").toString();

        if (s_verbose)
            qDebug() << "EkosLive reset phase 0 response - HTTP status:" << reply->attribute(
                         QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw EkosLive reset phase 0 response data:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();
                bool result = obj.value("result").toBool(false);

                if (result)
                {
                    success = true;
                    message = QString("Initial EkosLive reset successful for device %1. Restarting service...").arg(ipAddress);
                    qInfo() << message;

                    // Phase 1: Restart the ekoslive service
                    QJsonObject payload;
                    payload["operation"] = "restart";
                    payload["service"] = "ekoslive";
                    QJsonDocument restartDoc(payload);
                    QByteArray restartJsonData = restartDoc.toJson();

                    QString serviceRestartUrl = QString("http://%1:8624/api/service").arg(ipAddress);
                    QNetworkRequest restartRequest{QUrl(serviceRestartUrl)};
                    restartRequest.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
                    restartRequest.setRawHeader("Content-Type", "application/json");
                    restartRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

                    if (s_verbose)
                    {
                        qDebug() << "Making EkosLive service restart request to:" << serviceRestartUrl;
                        qDebug() << "JSON payload:" << restartJsonData;
                    }

                    QNetworkReply *restartReply = m_networkManager->post(restartRequest, restartJsonData);
                    restartReply->setProperty("ipAddress", ipAddress);
                    restartReply->setProperty("type", "ekoslive_reset_phase1");
                    QTimer::singleShot(15000, restartReply, [restartReply]()
                    {
                        if (restartReply->isRunning()) restartReply->abort();
                    });
                    m_pendingRequests++;
                    connect(restartReply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
                }
                else
                {
                    success = false;
                    message = QString("Initial EkosLive reset failed for %1: Server returned result=false").arg(ipAddress);
                    qCritical() << message;
                    emit ekosLiveResetCompleted(ipAddress, success, message);
                }
            }
            else
            {
                success = false;
                message = QString("Initial EkosLive reset failed for %1: Invalid JSON response - %2").arg(ipAddress, error.errorString());
                if (s_verbose)
                    qDebug() << message << "Raw data:" << data;
                emit ekosLiveResetCompleted(ipAddress, success, message);
            }
        }
        else
        {
            success = false;
            message = QString("Initial EkosLive reset failed for %1: Network error - %2").arg(ipAddress, reply->errorString());
            if (s_verbose)
                qDebug() << message;

            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            if (httpStatus != 0)
            {
                message += QString(" (HTTP %1)").arg(httpStatus);
            }
            emit ekosLiveResetCompleted(ipAddress, success, message);
        }

        if (!success)
        {
            setStatusText(message);
        }
        reply->deleteLater();
        return;
    }

    if (type == "ekoslive_reset_phase1")
    {
        bool success = false;
        QString message;
        QString ipAddress = reply->property("ipAddress").toString();

        if (s_verbose)
            qDebug() << "EkosLive reset phase 1 response - HTTP status:" << reply->attribute(
                         QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw EkosLive reset phase 1 response data:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();

                // Check for result field
                bool result = obj.value("result").toBool(false);
                if (result)
                {
                    success = true;
                    message = QString("EkosLive service restarted successfully for device %1. Starting image regeneration...").arg(ipAddress);
                    qInfo() << message;

                    // Wait 3 seconds then trigger image regeneration
                    QTimer::singleShot(3000, this, [this, ipAddress]()
                    {
                        triggerEkosLiveImageRegeneration(ipAddress);
                    });
                }
                else
                {
                    success = false;
                    message = QString("Failed to reset EkosLive for %1: Server returned result=false").arg(ipAddress);
                    qCritical() << message;
                    emit ekosLiveResetCompleted(ipAddress, success, message);
                }
            }
            else
            {
                success = false;
                message = QString("Failed to reset EkosLive for %1: Invalid JSON response - %2").arg(ipAddress, error.errorString());
                if (s_verbose)
                    qDebug() << message << "Raw data:" << data;
                emit ekosLiveResetCompleted(ipAddress, success, message);
            }
        }
        else
        {
            success = false;
            message = QString("Failed to reset EkosLive for %1: Network error - %2").arg(ipAddress, reply->errorString());
            qCritical() << message;

            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            if (httpStatus != 0)
            {
                message += QString(" (HTTP %1)").arg(httpStatus);
            }
            emit ekosLiveResetCompleted(ipAddress, success, message);
        }

        if (!success)
        {
            setStatusText(message);
        }
        reply->deleteLater();
        return;
    }

    if (type == "ekoslive_reset_phase2")
    {
        bool success = false;
        QString message;
        QString ipAddress = reply->property("ipAddress").toString();

        if (s_verbose)
            qDebug() << "EkosLive reset phase 2 (image regeneration) response - HTTP status:" << reply->attribute(
                         QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            success = true;
            message = QString("EkosLive image regeneration initiated for device %1. Polling progress...").arg(ipAddress);
            if (s_verbose)
                qDebug() << message;

            emit ekosLiveRegenerationProgressReceived(ipAddress, 5, "Starting regeneration...", true);

            int devIdx = -1;
            for (int i = 0; i < m_devices.size(); ++i)
            {
                if (m_devices[i].ipAddress() == ipAddress)
                {
                    devIdx = i;
                    break;
                }
            }

            int capturedIndex = devIdx;
            QTimer::singleShot(3000, this, [this, capturedIndex, ipAddress]()
            {
                if (capturedIndex >= 0 && capturedIndex < m_devices.size())
                {
                    checkEkosLiveRegenerationProgress(capturedIndex);
                }
                else
                {
                    emit ekosLiveResetCompleted(ipAddress, false, "Device not found for progress polling");
                }
            });
        }
        else
        {
            success = false;
            message = QString("EkosLive reset failed for device %1: Image regeneration encountered issues: %2").arg(ipAddress,
                      reply->errorString());
            qWarning() << message;
            emit ekosLiveResetCompleted(ipAddress, success, message);
            setStatusText(message);
        }

        reply->deleteLater();
        return;
    }

    if (type == "ekoslive_regeneration_progress")
    {
        int progress = 0;
        QString message = "Regenerating...";
        bool inProgress = false;
        int devIdx = reply->property("deviceIndex").toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "EkosLive regeneration progress response:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();
                progress = obj.value("progress").toInt(0);
                message = obj.value("message").toString("Regenerating...");
                inProgress = obj.value("inProgress").toBool(false);
            }
        }
        else
        {
            if (s_verbose)
                qDebug() << "EkosLive regeneration progress check failed:" << reply->errorString();
        }

        emit ekosLiveRegenerationProgressReceived(ipAddress, progress, message, inProgress);

        if (progress >= 100 && !inProgress)
        {
            qInfo() << "EkosLive regeneration complete for" << ipAddress;
            emit ekosLiveResetCompleted(ipAddress, true, "Ekoslive Reset is Successful");
            setStatusText("Ekoslive Reset is Successful");
        }
        else if (progress >= 100)
        {
            QTimer::singleShot(2000, this, [this, devIdx]()
            {
                if (devIdx >= 0 && devIdx < m_devices.size())
                    checkEkosLiveRegenerationProgress(devIdx);
            });
        }
        else
        {
            QTimer::singleShot(2000, this, [this, devIdx]()
            {
                if (devIdx >= 0 && devIdx < m_devices.size())
                    checkEkosLiveRegenerationProgress(devIdx);
            });
        }

        reply->deleteLater();
        return;
    }

    if (type == "network_reset")
    {
        bool success = false;
        QString message;

        if (s_verbose)
            qDebug() << "Network reset response - HTTP status:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw network reset response data:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();

                // Check for "success" field (actual API format)
                if (obj.contains("success"))
                {
                    QString successMessage = obj.value("success").toString();
                    if (!successMessage.isEmpty())
                    {
                        success = true;
                        message = QString("Network reset successful for device %1: %2").arg(ipAddress, successMessage);
                        qCritical() << message;
                    }
                    else
                    {
                        success = false;
                        message = QString("Failed to reset network for %1: Empty success message").arg(ipAddress);
                        qCritical() << message;
                    }
                }
                // Fallback: check for "result" field (generic format)
                else if (obj.contains("result"))
                {
                    bool result = obj.value("result").toBool(false);
                    if (result)
                    {
                        success = true;
                        message = QString("Network reset successfully initiated for device %1. The device will restart and may have a new IP address.").arg(
                                      ipAddress);
                        qInfo() << message;
                    }
                    else
                    {
                        success = false;
                        message = QString("Failed to reset network for %1: Server returned result=false").arg(ipAddress);
                        qCritical() << message;
                    }
                }
                else
                {
                    success = false;
                    message = QString("Failed to reset network for %1: Unknown response format").arg(ipAddress);
                    qCritical() << message;
                }
            }
            else
            {
                success = false;
                message = QString("Failed to reset network for %1: Invalid JSON response - %2").arg(ipAddress, error.errorString());
                qCritical() << message << "Raw data:" << data;
            }
        }
        else
        {
            success = false;
            message = QString("Failed to reset network for %1: Network error - %2").arg(ipAddress, reply->errorString());
            qCritical() << message;

            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            if (httpStatus != 0)
            {
                message += QString(" (HTTP %1)").arg(httpStatus);
            }
        }

        emit networkResetCompleted(ipAddress, success, message);
        setStatusText(message);
        reply->deleteLater();
        return;
    }

    if (type == "reboot")
    {
        bool success = false;
        QString message;
        QString ipAddress = reply->property("ipAddress").toString();

        if (s_verbose)
        {
            qDebug() << "Reboot response - HTTP status:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            qDebug() << "Reboot response - Network error:" << reply->error();
        }

        // For reboot/shutdown, we might not get a proper response since the device is going down
        // Consider it successful if we get any of these conditions:
        // 1. No network error (got a response)
        // 2. Connection errors (device is rebooting)
        // 3. Timeout errors (device went down before responding)

        if (reply->error() == QNetworkReply::NoError)
        {
            // Got a response, try to parse it
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw reboot response data:" << data;

            if (data.isEmpty())
            {
                // Empty response is fine for reboot - device is going down
                success = true;
                message = QString("Device %1 reboot initiated successfully. The device will be unavailable for a few minutes.").arg(
                              ipAddress);
                qInfo() << message;
            }
            else
            {
                // Try to parse JSON if we got data
                QJsonParseError error;
                QJsonDocument doc = QJsonDocument::fromJson(data, &error);

                if (error.error == QJsonParseError::NoError && doc.isObject())
                {
                    QJsonObject obj = doc.object();
                    if (obj.contains("result") && obj.value("result").toBool(false))
                    {
                        success = true;
                        message = QString("Device %1 reboot initiated successfully. The device will be unavailable for a few minutes.").arg(
                                      ipAddress);
                        qInfo() << message;
                    }
                    else
                    {
                        // Even if result is false, the device might still be rebooting
                        success = true;
                        message = QString("Device %1 reboot command sent. The device should be rebooting now.").arg(ipAddress);
                        qWarning() << message;
                    }
                }
                else
                {
                    // Invalid JSON, but command was sent - assume success
                    success = true;
                    message = QString("Device %1 reboot command sent. The device should be rebooting now.").arg(ipAddress);
                    qCritical() << message;
                }
            }
        }
        else if (reply->error() == QNetworkReply::ConnectionRefusedError ||
                 reply->error() == QNetworkReply::RemoteHostClosedError ||
                 reply->error() == QNetworkReply::TimeoutError ||
                 reply->error() == QNetworkReply::HostNotFoundError ||
                 reply->error() == QNetworkReply::UnknownNetworkError)
        {
            // Connection errors likely mean the device is already rebooting - this is success!
            success = true;
            message = QString("Device %1 reboot initiated successfully. Connection lost as expected - device is rebooting.").arg(
                          ipAddress);
            qInfo() << message;
        }
        else
        {
            // Other network errors - treat as potential success since command might have been received
            success = true;
            message = QString("Device %1 reboot command sent. Network error occurred (%2), but device may be rebooting.").arg(ipAddress,
                      reply->errorString());
            if (s_verbose)
                qDebug() << message;
        }

        emit rebootCompleted(ipAddress, success, message);
        setStatusText(message);
        reply->deleteLater();
        return;
    }

    if (type == "shutdown")
    {
        bool success = false;
        QString message;
        QString ipAddress = reply->property("ipAddress").toString();

        if (s_verbose)
        {
            qDebug() << "Shutdown response - HTTP status:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            qDebug() << "Shutdown response - Network error:" << reply->error();
        }

        // For reboot/shutdown, we might not get a proper response since the device is going down
        // Consider it successful if we get any of these conditions:
        // 1. No network error (got a response)
        // 2. Connection errors (device is shutting down)
        // 3. Timeout errors (device went down before responding)

        if (reply->error() == QNetworkReply::NoError)
        {
            // Got a response, try to parse it
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw shutdown response data:" << data;

            if (data.isEmpty())
            {
                // Empty response is fine for shutdown - device is going down
                success = true;
                message = QString("Device %1 shutdown initiated successfully. The device will power off.").arg(ipAddress);
                qInfo() << message;
            }
            else
            {
                // Try to parse JSON if we got data
                QJsonParseError error;
                QJsonDocument doc = QJsonDocument::fromJson(data, &error);

                if (error.error == QJsonParseError::NoError && doc.isObject())
                {
                    QJsonObject obj = doc.object();
                    if (obj.contains("result") && obj.value("result").toBool(false))
                    {
                        success = true;
                        message = QString("Device %1 shutdown initiated successfully. The device will power off.").arg(ipAddress);
                        qInfo() << message;
                    }
                    else
                    {
                        // Even if result is false, the device might still be shutting down
                        success = true;
                        message = QString("Device %1 shutdown command sent. The device should be powering off now.").arg(ipAddress);
                        qCritical() << message;
                    }
                }
                else
                {
                    // Invalid JSON, but command was sent - assume success
                    success = true;
                    message = QString("Device %1 shutdown command sent. The device should be powering off now.").arg(ipAddress);
                    qCritical() << message;
                }
            }
        }
        else if (reply->error() == QNetworkReply::ConnectionRefusedError ||
                 reply->error() == QNetworkReply::RemoteHostClosedError ||
                 reply->error() == QNetworkReply::TimeoutError ||
                 reply->error() == QNetworkReply::HostNotFoundError ||
                 reply->error() == QNetworkReply::UnknownNetworkError)
        {
            // Connection errors likely mean the device is already shutting down - this is success!
            success = true;
            message = QString("Device %1 shutdown initiated successfully. Connection lost as expected - device is powering off.").arg(
                          ipAddress);
            qDebug() << message;
        }
        else
        {
            // Other network errors - treat as potential success since command might have been received
            success = true;
            message = QString("Device %1 shutdown command sent. Network error occurred (%2), but device may be shutting down.").arg(
                          ipAddress, reply->errorString());
            qDebug() << message;
        }

        emit shutdownCompleted(ipAddress, success, message);
        setStatusText(message);
        reply->deleteLater();
        return;
    }

    if (type == "get_pictures_directory")
    {
        if (s_verbose)
            qDebug() << "Pictures directory query response - HTTP status:" << reply->attribute(
                         QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw pictures directory response data:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();
                bool result = obj.value("result").toBool(false);

                QString directory;
                if (result)
                {
                    if (obj.contains("payload"))
                    {
                        if (obj["payload"].isString())
                            directory = obj["payload"].toString();
                        else if (obj["payload"].isObject())
                            directory = obj["payload"].toObject().value("directory").toString();
                    }
                }

                if (result && !directory.isEmpty())
                {
                    if (s_verbose)
                        qDebug() << "Received pictures directory for" << ipAddress << ":" << directory;
                    m_picturesDirectories[ipAddress] = directory;
                    emit picturesDirectoryReceived(ipAddress, directory);
                }
                else
                {
                    qCritical() << "Failed to get pictures directory for" << ipAddress << ": Server returned result=" << result <<
                                   "Directory empty:" << directory.isEmpty();
                    emit picturesDirectoryReceived(ipAddress, "/home/stellarmate/Pictures"); // fallback
                }
            }
            else
            {
                qCritical() << "Failed to parse pictures directory response for" << ipAddress << ":" << error.errorString();
                emit picturesDirectoryReceived(ipAddress, "/home/stellarmate/Pictures"); // fallback
            }
        }
        else
        {
            qCritical() << "Network error getting pictures directory for" << ipAddress << ":" << reply->errorString();
            emit picturesDirectoryReceived(ipAddress, "/home/stellarmate/Pictures"); // fallback
        }

        reply->deleteLater();
        return;
    }

    if (type == "update_pictures_directory")
    {
        QString newDirectory = reply->property("newDirectory").toString();
        bool success = false;
        QString message;

        if (s_verbose)
            qDebug() << "Pictures directory update response - HTTP status:" << reply->attribute(
                         QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw pictures directory update response data:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();
                bool result = obj.value("result").toBool(false);

                if (result)
                {
                    success = true;
                    message = QString("Pictures directory successfully updated to '%1' for device %2 . Make sure to reboot the system to monitor the directory.").arg(
                                  newDirectory, ipAddress);
                    qInfo() << message;

                    // Update our local cache
                    m_picturesDirectories[ipAddress] = newDirectory;
                }
                else
                {
                    success = false;
                    message = QString("Failed to update pictures directory for %1: Server returned result=false").arg(ipAddress);
                    qCritical() << message;
                }
            }
            else
            {
                success = false;
                message = QString("Failed to update pictures directory for %1: Invalid JSON response - %2").arg(ipAddress,
                          error.errorString());
                if (s_verbose)
                    qDebug() << message << "Raw data:" << data;
            }
        }
        else
        {
            success = false;
            message = QString("Failed to update pictures directory for %1: Network error - %2").arg(ipAddress, reply->errorString());
            qDebug() << message;

            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            if (httpStatus != 0)
            {
                message += QString(" (HTTP %1)").arg(httpStatus);
            }
        }

        emit picturesDirectoryUpdated(ipAddress, success, message);
        setStatusText(message);
        reply->deleteLater();
        return;
    }

    if (type == "update_hostname")
    {
        QString newHostname = reply->property("newHostname").toString();
        bool success = false;
        QString message;

        if (s_verbose)
            qDebug() << "Hostname update response - HTTP status:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw response data:" << data;

            // Parse JSON response
            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();
                bool result = obj.value("result").toBool(false);

                if (result)
                {
                    success = true;
                    message = QString("Hostname successfully updated to '%1' for device %2").arg(newHostname, ipAddress);
                    qDebug() << message;

                    // Refresh device info to get the updated hostname
                    queryDeviceInfo(ipAddress);
                }
                else
                {
                    success = false;
                    message = QString("Failed to update hostname for %1: Server returned result=false").arg(ipAddress);
                    qDebug() << message;
                }
            }
            else
            {
                success = false;
                message = QString("Failed to update hostname for %1: Invalid JSON response - %2").arg(ipAddress, error.errorString());
                qDebug() << message << "Raw data:" << data;
            }
        }
        else
        {
            success = false;
            message = QString("Failed to update hostname for %1: Network error - %2").arg(ipAddress, reply->errorString());
            qDebug() << message;

            // Add HTTP status if available
            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            if (httpStatus != 0)
            {
                message += QString(" (HTTP %1)").arg(httpStatus);
            }
        }

        emit hostnameUpdated(ipAddress, success, message);
        setStatusText(message);
        reply->deleteLater();
        return;
    }

    if (type == "activate_direct_ethernet")
    {
        bool success = false;
        QString message;

        if (s_verbose)
            qDebug() << "Activate direct ethernet response - HTTP status:" << reply->attribute(
                         QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw activate direct ethernet response data:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();
                bool result = obj.value("result").toBool(false);

                if (result)
                {
                    success = true;
                    message = QString("Direct ethernet activated successfully for device %1.").arg(ipAddress);
                    qDebug() << message;
                }
                else
                {
                    success = false;
                    message = QString("Failed to activate direct ethernet for %1: Server returned result=false").arg(ipAddress);
                    qDebug() << message;
                }
            }
            else
            {
                success = false;
                message = QString("Failed to activate direct ethernet for %1: Invalid JSON response - %2").arg(ipAddress,
                          error.errorString());
                qDebug() << message << "Raw data:" << data;
            }
        }
        else
        {
            success = false;
            message = QString("Failed to activate direct ethernet for %1: Network error - %2").arg(ipAddress, reply->errorString());
            qDebug() << message;

            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            if (httpStatus != 0)
            {
                message += QString(" (HTTP %1)").arg(httpStatus);
            }
        }

        emit ethernetActivationCompleted(ipAddress, success, message);
        setStatusText(message);
        reply->deleteLater();
        return;
    }

    if (type == "deactivate_direct_ethernet")
    {
        bool success = false;
        QString message;

        if (s_verbose)
            qDebug() << "Deactivate direct ethernet response - HTTP status:" << reply->attribute(
                         QNetworkRequest::HttpStatusCodeAttribute).toInt();

        if (reply->error() == QNetworkReply::NoError)
        {
            QByteArray data = reply->readAll();
            if (s_verbose)
                qDebug() << "Raw deactivate direct ethernet response data:" << data;

            QJsonParseError error;
            QJsonDocument doc = QJsonDocument::fromJson(data, &error);

            if (error.error == QJsonParseError::NoError && doc.isObject())
            {
                QJsonObject obj = doc.object();
                bool result = obj.value("result").toBool(false);

                if (result)
                {
                    success = true;
                    message = QString("Direct ethernet deactivated successfully for device %1.").arg(ipAddress);
                    qDebug() << message;
                }
                else
                {
                    success = false;
                    message = QString("Failed to deactivate direct ethernet for %1: Server returned result=false").arg(ipAddress);
                    qDebug() << message;
                }
            }
            else
            {
                success = false;
                message = QString("Failed to deactivate direct ethernet for %1: Invalid JSON response - %2").arg(ipAddress,
                          error.errorString());
                qDebug() << message << "Raw data:" << data;
            }
        }
        else
        {
            success = false;
            message = QString("Failed to deactivate direct ethernet for %1: Network error - %2").arg(ipAddress, reply->errorString());
            qDebug() << message;

            int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            if (httpStatus != 0)
            {
                message += QString(" (HTTP %1)").arg(httpStatus);
            }
        }

        emit ethernetDeactivationCompleted(ipAddress, success, message);
        setStatusText(message);
        reply->deleteLater();
        return;
    }


    bool isRefreshOperation = m_activeRefreshes.contains(ipAddress);

    // Existing code for hostname, version, and model
    StellarMateDevice currentDevice = m_tempDevices.value(ipAddress, StellarMateDevice());
    if (currentDevice.ipAddress().isEmpty())
    {
        currentDevice.setIpAddress(ipAddress);
        currentDevice.setIsLocal(false);
        currentDevice.setIsOnline(false);
        currentDevice.setHostname("Unknown");
        currentDevice.setVersion("Unknown");
        currentDevice.setModel("Unknown");
    }

    std::tuple<bool, bool, bool, bool> status = m_deviceInfoStatus.value(ipAddress, std::make_tuple(false, false, false,
        false));

    bool currentRequestSuccessfulAndValid = false;
    if (reply->error() == QNetworkReply::NoError)
    {
        QByteArray data = reply->readAll();
        QJsonParseError error;
        QJsonDocument doc = QJsonDocument::fromJson(data, &error);

        if (error.error == QJsonParseError::NoError && doc.isObject())
        {
            QJsonObject obj = doc.object();
            if (type == "hostname")
            {
                QString hostname = obj.value("hostname").toString("Unknown");
                if (hostname != "Unknown" && !hostname.isEmpty() && hostname != "N/A")
                {
                    currentDevice.setHostname(hostname);
                    std::get<0>(status) = true;
                    currentRequestSuccessfulAndValid = true;
                    if (isRefreshOperation)
                    {
                        m_activeRefreshes[ipAddress].hostnameReceived = 1;
                        if (s_verbose)
                            qDebug() << "Refresh: hostname received successfully for" << ipAddress;
                    }
                    if (s_verbose)
                        qDebug() << "Received hostname for" << ipAddress << ":" << currentDevice.hostname();
                }
                else
                {
                    qDebug() << "Received invalid/empty hostname for" << ipAddress;
                    std::get<0>(status) = false;

                    if (isRefreshOperation)
                    {
                        m_activeRefreshes[ipAddress].hostnameReceived = -1;
                        qDebug() << "Refresh: hostname failed for" << ipAddress;
                    }
                }
            }
            else if (type == "version")
            {
                QString version = obj.value("version").toString("Unknown");
                if (version != "Unknown" && !version.isEmpty() && version != "N/A")
                {
                    currentDevice.setVersion(version);
                    std::get<1>(status) = true;
                    currentRequestSuccessfulAndValid = true;
                    if (isRefreshOperation)
                    {
                        m_activeRefreshes[ipAddress].versionReceived = 1;
                        if (s_verbose)
                            qDebug() << "Refresh: version received successfully for" << ipAddress;
                    }
                    if (s_verbose)
                        qDebug() << "Received version for" << ipAddress << ":" << currentDevice.version();
                }
                else
                {
                    qDebug() << "Received invalid/empty version for" << ipAddress;
                    std::get<1>(status) = false;

                    if (isRefreshOperation)
                    {
                        m_activeRefreshes[ipAddress].versionReceived = -1;
                        qDebug() << "Refresh: version failed for" << ipAddress;
                    }
                }
            }
            else if (type == "model")
            {
                QString model = obj.value("model").toString("Unknown");
                if (s_verbose)
                    qDebug() << "Raw model API response for" << ipAddress << ":" << data;
                if (model != "Unknown" && !model.isEmpty() && model != "N/A")
                {
                    currentDevice.setModel(model);
                    std::get<2>(status) = true;
                    currentRequestSuccessfulAndValid = true;

                    if (isRefreshOperation)
                    {
                        m_activeRefreshes[ipAddress].modelReceived = 1;
                        if (s_verbose)
                            qDebug() << "Refresh: model received successfully for" << ipAddress;
                    }
                    if (s_verbose)
                        qDebug() << "Received model for" << ipAddress << ":" << currentDevice.model();
                }
                else
                {
                    qDebug() << "Received invalid/empty model for" << ipAddress;
                    std::get<2>(status) = false;

                    if (isRefreshOperation)
                    {
                        m_activeRefreshes[ipAddress].modelReceived = -1;
                        qDebug() << "Refresh: model failed for" << ipAddress;
                    }
                }
            }
            else if (type == "machine_id")
            {
                QString machineId = obj.value("machine_id").toString("Unknown");
                if (machineId != "Unknown" && !machineId.isEmpty() && machineId != "N/A")
                {
                    currentDevice.setMachineId(machineId);
                    std::get<3>(status) = true;
                    currentRequestSuccessfulAndValid = true;
                    if (s_verbose)
                        qDebug() << "Received machine_id for" << ipAddress << ":" << machineId;
                }
            }


        }
        else
        {
            qDebug() << "JSON parse error for" << ipAddress << "type:" << type << "- Error:" << error.errorString();
            if (type == "hostname")
            {
                std::get<0>(status) = false;
                if (isRefreshOperation) m_activeRefreshes[ipAddress].hostnameReceived = -1;
            }
            else if (type == "version")
            {
                std::get<1>(status) = false;
                if (isRefreshOperation) m_activeRefreshes[ipAddress].versionReceived = -1;
            }
            else if (type == "model")
            {
                std::get<2>(status) = false;
                if (isRefreshOperation) m_activeRefreshes[ipAddress].modelReceived = -1;
            }

        }
    }
    else
    {
        // Network error - mark as failed
        qDebug() << "Network error for" << ipAddress << type << ":" << reply->errorString();

        if (type == "hostname")
        {
            std::get<0>(status) = false;
            if (isRefreshOperation) m_activeRefreshes[ipAddress].hostnameReceived = -1;
        }
        else if (type == "version")
        {
            std::get<1>(status) = false;
            if (isRefreshOperation) m_activeRefreshes[ipAddress].versionReceived = -1;
        }
        else if (type == "model")
        {
            std::get<2>(status) = false;
            if (isRefreshOperation) m_activeRefreshes[ipAddress].modelReceived = -1;
        }
    }

    if (isRefreshOperation)
    {
        checkRefreshCompletion(ipAddress);
    }
    m_tempDevices[ipAddress] = currentDevice;
    m_deviceInfoStatus[ipAddress] = status;

    if (std::get<0>(status) && std::get<1>(status) && std::get<2>(status) && std::get<3>(status))
    {
        if (currentDevice.hostname() != "Unknown" && !currentDevice.hostname().isEmpty() && currentDevice.hostname() != "N/A" &&
                currentDevice.version() != "Unknown" && !currentDevice.version().isEmpty() && currentDevice.version() != "N/A" &&
                currentDevice.model() != "Unknown" && !currentDevice.model().isEmpty() && currentDevice.model() != "N/A")
        {
            currentDevice.setIsOnline(true);
            if (s_verbose)
                qDebug() << "Adding device with valid hostname, version, and model:" << ipAddress;

            // If this was found via mDNS, increment the counter (even if mDNS phase has ended)
            if (m_mdnsFoundIps.contains(ipAddress))
            {
                m_mdnsDevicesFound++;
                if (s_verbose)
                {
                    qDebug() << "Device" << ipAddress << "confirmed as StellarMate via mDNS (total mDNS devices:" << m_mdnsDevicesFound << ")";
                    qDebug() << "mDNS phase active:" << m_mdnsPhase;
                }
            }

            addOrUpdateDevice(currentDevice);
        }
        else
        {
            qDebug() << "Not adding device" << ipAddress <<
                        "due to invalid hostname, version, or model. Removing from m_mdnsFoundIps if present.";
            // If a device found via mDNS turns out to be invalid, remove it from m_mdnsFoundIps
            // to prevent it from being considered in m_mdnsDevicesFound count.
            m_mdnsFoundIps.removeOne(ipAddress);
            int existingIndex = -1;
            for (int i = 0; i < m_devices.size(); ++i)
            {
                if (m_devices[i].ipAddress() == ipAddress)
                {
                    existingIndex = i;
                    break;
                }
            }
            if (existingIndex != -1)
            {
                qDebug() << "Removing device" << ipAddress << "due to invalid data. Hostname:" << currentDevice.hostname()
                         << "Version:" << currentDevice.version() << "Model:" << currentDevice.model();
                beginRemoveRows(QModelIndex(), existingIndex, existingIndex);
                m_devices.removeAt(existingIndex);
                endRemoveRows();
                emit deviceCountChanged();
                emit deviceRemoved(ipAddress);
            }
        }

        m_tempDevices.remove(ipAddress);
        m_deviceInfoStatus.remove(ipAddress);
    }

    reply->deleteLater();

    // Check if we should complete discovery.
    // The mDNS phase completion is handled by onMdnsTimeout -> checkMdnsCompletion.
    // This ensures the full mDNS discovery period is observed.
    if (m_isScanning && m_pendingRequests == 0 && !m_mdnsPhase)
    {
        // If mDNS phase is already over and all requests are done, complete discovery.
        // Otherwise, mDNS timeout will handle it.
        onDiscoveryTimeout();
    }
}

void DeviceDiscovery::onDiscoveryTimeout()
{
    setScanning(false);
    m_discoveryTimer->stop();
    m_mdnsTimer->stop();
    m_mdnsPhase = false;

    if (m_devices.size() == 0)
    {
        setStatusText("Scan completed. No StellarMate devices found on the network.");
    }
    else
    {
        setStatusText(QString("Scan completed. Found %1 StellarMate device(s)").arg(m_devices.size()));
        startPeriodicStatusUpdates();
    }
}

void DeviceDiscovery::setScanning(bool scanning)
{
    if (m_isScanning != scanning)
    {
        m_isScanning = scanning;
        emit isScanningChanged();
    }
}

void DeviceDiscovery::setStatusText(const QString &text)
{
    if (m_statusText != text)
    {
        m_statusText = text;
        emit statusTextChanged();
    }
}

void DeviceDiscovery::addOrUpdateDevice(const StellarMateDevice &device)
{
    // Additional validation before adding
    if (device.hostname() == "Unknown" || device.hostname().isEmpty() || device.hostname() == "N/A" ||
            device.version() == "Unknown" || device.version().isEmpty() || device.version() == "N/A" ||
            device.model() == "Unknown" || device.model().isEmpty() || device.model() == "N/A")
    {
        qDebug() << "Skipping device addition due to invalid hostname, version, or model";
        return;
    }

    // Check if device already exists - match by machine_id OR IP address
    for (int i = 0; i < m_devices.size(); ++i)
    {
        StellarMateDevice &existingDevice = m_devices[i];

        // Match by machine_id (preferred)
        bool matchByMachineId = (!device.machineId().isEmpty() &&
                                 device.machineId() != "Unknown" &&
                                 existingDevice.machineId() == device.machineId());

        // Match by IP address (fallback for devices without machine_id yet)
        bool matchByIp = (existingDevice.ipAddress() == device.ipAddress());

        if (matchByMachineId || matchByIp)
        {
            qDebug() << "Updating existing device at index" << i << "IP:" << device.ipAddress();

            // Update the existing device
            existingDevice.setHostname(device.hostname());
            existingDevice.setVersion(device.version());
            existingDevice.setModel(device.model());
            existingDevice.setIsOnline(device.isOnline());
            existingDevice.setIsLocal(device.isLocal() || existingDevice.isLocal());

            // Update machine_id if we now have it
            if (!device.machineId().isEmpty() && device.machineId() != "Unknown")
            {
                existingDevice.setMachineId(device.machineId());
            }

            // Handle secondary IPs
            for (const QString &secondaryIp : device.secondaryIpAddresses())
            {
                if (!existingDevice.secondaryIpAddresses().contains(secondaryIp))
                {
                    existingDevice.addSecondaryIp(secondaryIp);
                }
            }

            QModelIndex topLeft = createIndex(i, 0);
            QModelIndex bottomRight = createIndex(i, 0);
            emit dataChanged(topLeft, bottomRight);
            return;  // ← IMPORTANT: Return here to prevent adding duplicate
        }
    }

    // No existing device found - add as new
    if (s_verbose)
        qDebug() << "Adding NEW device:" << device.ipAddress() << "machine_id:" << device.machineId();
    int newRow = m_devices.size();
    beginInsertRows(QModelIndex(), newRow, newRow);
    m_devices.append(device);
    endInsertRows();

    emit deviceCountChanged();
    emit deviceAdded(device.ipAddress());
}

void DeviceDiscovery::updateDeviceHostname(int index, const QString &newHostname)
{
    if (index < 0 || index >= m_devices.size())
    {
        emit hostnameUpdated("", false, "Invalid device index");
        return;
    }

    const StellarMateDevice &device = m_devices.at(index);
    QString ipAddress = device.ipAddress();

    // Validate hostname
    QString finalHostName = newHostname.simplified();
    finalHostName.replace(" ", "");
    if (finalHostName.isEmpty())
    {
        emit hostnameUpdated(ipAddress, false, "Hostname cannot be empty");
        return;
    }

    setStatusText(QString("Updating hostname for %1 to %2...").arg(ipAddress, finalHostName));

    // Try different API endpoint formats - the API might expect a different format
    QString hostnameUrl = QString("http://%1:8624/api/info/hostname/%2").arg(ipAddress, finalHostName);
    QNetworkRequest request{QUrl(hostnameUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setRawHeader("Content-Type", "application/json");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    qDebug() << "Making hostname update request to:" << hostnameUrl;

    // Try POST with empty body first (as in your original code)
    QNetworkReply *reply = m_networkManager->post(request, QByteArray());
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "update_hostname");
    reply->setProperty("newHostname", finalHostName);
    QTimer::singleShot(10000, reply, [reply]() // Increased timeout to 10s
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::startNetworkScan()
{
    qDebug() << "Starting network scan (brute force discovery)";
    setStatusText("Performing deep network scan for StellarMate devices...");

    // Get all network interfaces and scan their subnets
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();

    // Check if we already have a local device to avoid overwriting it
    bool hasLocalDevice = false;
    QString localIP;
    for (const auto &device : m_devices)
    {
        if (device.isLocal())
        {
            hasLocalDevice = true;
            localIP = device.ipAddress();
            break;
        }
    }

    for (const QNetworkInterface &interface : interfaces)
    {
        if (!(interface.flags() & QNetworkInterface::IsUp) ||
                !(interface.flags() & QNetworkInterface::IsRunning) ||
                (interface.flags() & QNetworkInterface::IsLoopBack))
        {
            continue;
        }

        QList<QNetworkAddressEntry> entries = interface.addressEntries();
        for (const QNetworkAddressEntry &entry : entries)
        {
            QHostAddress address = entry.ip();
            if (address.protocol() != QAbstractSocket::IPv4Protocol)
            {
                continue;
            }

            // Calculate the network address and scan range based on netmask
            QHostAddress netmask = entry.netmask();
            quint32 networkAddr = address.toIPv4Address() & netmask.toIPv4Address();
            quint32 broadcastAddr = networkAddr | (~netmask.toIPv4Address());

            // Skip very large networks to avoid excessive scanning
            quint32 networkSize = broadcastAddr - networkAddr;
            if (networkSize > 512) // Skip networks larger than /23
            {
                qDebug() << "Skipping large network" << QHostAddress(networkAddr).toString()
                         << "size:" << networkSize;
                continue;
            }

            qDebug() << "Scanning network:" << QHostAddress(networkAddr).toString()
                     << "to" << QHostAddress(broadcastAddr).toString()
                     << "size:" << networkSize;

            // Scan the calculated range (skip network and broadcast addresses)
            for (quint32 addr = networkAddr + 1; addr < broadcastAddr; ++addr)
            {
                QString testIp = QHostAddress(addr).toString();

                // Skip if we already found this IP via mDNS
                if (m_mdnsFoundIps.contains(testIp))
                {
                    qDebug() << "Skipping" << testIp << "as it was already discovered via mDNS";
                    continue;
                }

                // Skip local device IP if we already have it detected as local
                if (hasLocalDevice && (testIp == localIP || testIp == "127.0.0.1"))
                {
                    qDebug() << "Skipping" << testIp << "as it's already detected as local device";
                    continue;
                }

                queryDeviceInfo(testIp);
            }
        }
    }

    // Removed hardcoded common IPs as per new discovery strategy.
    // The mDNS service discovery for _http._tcp.local will handle finding devices.
}

// Helper function to construct URLs
QString getURLForIP(const QString &ip, const QString &path)
{
    return QString("http://%1:8624%2").arg(ip, path);
}

void DeviceDiscovery::activateDirectEthernet(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        emit ethernetActivationCompleted("", false, "Invalid device index");
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        emit ethernetActivationCompleted(ipAddress, false, "Device IP address is empty");
        return;
    }

    setStatusText(QString("Activating direct ethernet for device %1...").arg(ipAddress));

    QString activateUrl = getURLForIP(ipAddress, "/api/system/activate_direct_ethernet");
    QNetworkRequest request{QUrl(activateUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setRawHeader("Content-Type", "application/json");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    qDebug() << "Making activate direct ethernet request to:" << activateUrl;

    QNetworkReply *reply = m_networkManager->post(request, QByteArray());
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "activate_direct_ethernet");
    QTimer::singleShot(10000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}

void DeviceDiscovery::deactivateDirectEthernet(int deviceIndex)
{
    if (deviceIndex < 0 || deviceIndex >= m_devices.size())
    {
        emit ethernetDeactivationCompleted("", false, "Invalid device index");
        return;
    }

    const StellarMateDevice &device = m_devices[deviceIndex];
    QString ipAddress = device.ipAddress();

    if (ipAddress.isEmpty())
    {
        emit ethernetDeactivationCompleted(ipAddress, false, "Device IP address is empty");
        return;
    }

    setStatusText(QString("Deactivating direct ethernet for device %1...").arg(ipAddress));

    QString deactivateUrl = getURLForIP(ipAddress, "/api/system/deactivate_direct_ethernet");
    QNetworkRequest request{QUrl(deactivateUrl)};
    request.setRawHeader("User-Agent", "StellarMate-Discovery/1.0");
    request.setRawHeader("Content-Type", "application/json");
    request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);

    qDebug() << "Making deactivate direct ethernet request to:" << deactivateUrl;

    QNetworkReply *reply = m_networkManager->post(request, QByteArray());
    reply->setProperty("ipAddress", ipAddress);
    reply->setProperty("type", "deactivate_direct_ethernet");
    QTimer::singleShot(10000, reply, [reply]()
    {
        if (reply->isRunning()) reply->abort();
    });
    m_pendingRequests++;
    connect(reply, &QNetworkReply::finished, this, &DeviceDiscovery::onNetworkReplyFinished);
}
