/*
 * iDescriptor: A free and open-source idevice management tool.
 *
 * Copyright (C) 2025 Uncore <https://github.com/uncor3>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */

#include "networkdeviceswidget.h"
#ifdef __linux__
#include "core/services/avahi/avahi_service.h"
#else
#include "core/services/dnssd/dnssd_service.h"
#endif

#include <QApplication>
#include <QFrame>
#include <QHBoxLayout>
#include <QLabel>
#include <QPalette>

NetworkDevicesWidget::NetworkDevicesWidget(QWidget *parent) : Tool(parent)
{
    setWindowTitle("Network Devices - iDescriptor");
    setMinimumSize(300, 300);
    setMaximumSize(500, 500);
    setupUI();

    connect(NetworkDeviceProvider::sharedInstance(),
            &NetworkDeviceProvider::deviceAdded, this,
            &NetworkDevicesWidget::onWirelessDeviceAdded);
    connect(NetworkDeviceProvider::sharedInstance(),
            &NetworkDeviceProvider::deviceRemoved, this,
            &NetworkDevicesWidget::onWirelessDeviceRemoved);

    updateDeviceList();
    setMaximumHeight(sizeHint().height());
}

NetworkDevicesWidget::~NetworkDevicesWidget() {}

void NetworkDevicesWidget::setupUI()
{
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->setContentsMargins(10, 10, 10, 10);
    mainLayout->setSpacing(10);

    // Status label
    m_statusLabel = new QLabel("Scanning for network devices...");
    QFont statusFont = m_statusLabel->font();
    statusFont.setPointSize(12);
    statusFont.setWeight(QFont::Medium);
    m_statusLabel->setFont(statusFont);
    m_statusLabel->setAlignment(Qt::AlignCenter);
    mainLayout->addWidget(m_statusLabel);

    // Device group
    m_deviceGroup = new QGroupBox("Network Devices");
    QFont groupFont = m_deviceGroup->font();
    groupFont.setPointSize(14);
    groupFont.setWeight(QFont::Bold);
    m_deviceGroup->setFont(groupFont);

    QVBoxLayout *groupLayout = new QVBoxLayout(m_deviceGroup);
    groupLayout->setContentsMargins(5, 15, 5, 5);
    groupLayout->setSpacing(0);

    // Scroll area
    m_scrollArea = new QScrollArea();
    m_scrollArea->setWidgetResizable(true);
    m_scrollArea->setMinimumHeight(200);
    m_scrollArea->setMaximumHeight(400);
    m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_scrollArea->setStyleSheet(
        "QScrollArea { background: transparent; border: none; }");

    // Scroll content
    m_scrollContent = new QWidget();
    m_deviceLayout = new QVBoxLayout(m_scrollContent);
    m_deviceLayout->setContentsMargins(5, 5, 5, 5);
    m_deviceLayout->setSpacing(8);
    m_deviceLayout->addStretch();

    m_scrollArea->setWidget(m_scrollContent);
    groupLayout->addWidget(m_scrollArea);

    mainLayout->addWidget(m_deviceGroup);
    mainLayout->addStretch();
}

void NetworkDevicesWidget::createDeviceCard(const NetworkDevice &device)
{
    // Main card frame
    QWidget *card = new QWidget();

    QVBoxLayout *cardLayout = new QVBoxLayout(card);
    cardLayout->setContentsMargins(12, 10, 12, 10);
    cardLayout->setSpacing(4);

    // Device name (primary)
    QLabel *nameLabel = new QLabel(device.name);
    nameLabel->setWordWrap(true);
    QFont nameFont = nameLabel->font();
    nameFont.setPointSize(13);
    nameFont.setWeight(QFont::Medium);
    nameLabel->setFont(nameFont);
    QPalette namePalette = nameLabel->palette();
    namePalette.setColor(QPalette::WindowText,
                         palette().color(QPalette::WindowText));
    nameLabel->setPalette(namePalette);

    // Device info container
    QWidget *infoContainer = new QWidget();
    QHBoxLayout *infoLayout = new QHBoxLayout(infoContainer);
    infoLayout->setContentsMargins(0, 0, 0, 0);
    infoLayout->setSpacing(12);

    // Address info
    QLabel *addressLabel = new QLabel(QString("IP: %1").arg(device.address));
    QFont addressFont = addressLabel->font();
    addressFont.setPointSize(11);
    addressLabel->setFont(addressFont);
    QPalette addressPalette = addressLabel->palette();
    QColor secondaryColor = palette().color(QPalette::WindowText);
    secondaryColor.setAlpha(180);
    addressPalette.setColor(QPalette::WindowText, secondaryColor);
    addressLabel->setPalette(addressPalette);

    // Port info
    QLabel *portLabel = new QLabel(QString("Port: %1").arg(device.port));
    portLabel->setFont(addressFont);
    portLabel->setPalette(addressPalette);

    infoLayout->addWidget(addressLabel);
    infoLayout->addWidget(portLabel);
    infoLayout->addStretch();

    QLabel *statusIndicator = new QLabel("●");
    statusIndicator->setStyleSheet(
        QString("QLabel { font-size: 14px; color: %1; }")
#ifdef WIN32
            .arg(COLOR_ACCENT_BLUE.name()));
#else
            .arg(COLOR_GREEN.name()));
#endif

    infoLayout->addWidget(statusIndicator);

    cardLayout->addWidget(nameLabel);
    cardLayout->addWidget(infoContainer);

    // Store the device info as property for later removal
    card->setProperty("deviceName", device.name);
    card->setProperty("deviceAddress", device.address);

    // Insert before the stretch
    m_deviceLayout->insertWidget(m_deviceLayout->count() - 1, card);
    m_deviceCards.append(card);
}

void NetworkDevicesWidget::clearDeviceCards()
{
    for (QWidget *card : m_deviceCards) {
        card->deleteLater();
    }
    m_deviceCards.clear();
}

void NetworkDevicesWidget::updateDeviceList()
{
    clearDeviceCards();

    QMap<QString, NetworkDevice> devices =
        NetworkDeviceProvider::sharedInstance()->getNetworkDevices();

    if (devices.isEmpty()) {
        m_statusLabel->setText("No network devices found");
    } else {
        m_statusLabel->setText(
            QString("Found %1 network device(s)").arg(devices.count()));

        for (const NetworkDevice &device : devices) {
            createDeviceCard(device);
        }
    }
}

void NetworkDevicesWidget::onWirelessDeviceAdded(const NetworkDevice &device)
{
    createDeviceCard(device);

    // Update status
    int deviceCount = m_deviceCards.count();
    m_statusLabel->setText(
        QString("Found %1 network device(s)").arg(deviceCount));
}

void NetworkDevicesWidget::onWirelessDeviceRemoved(const QString &deviceName)
{
    // Find and remove the corresponding card
    for (int i = 0; i < m_deviceCards.count(); ++i) {
        QWidget *card = m_deviceCards[i];
        if (card->property("deviceName").toString() == deviceName) {
            m_deviceCards.removeAt(i);
            card->deleteLater();
            break;
        }
    }

    // Update status
    int deviceCount = m_deviceCards.count();
    if (deviceCount == 0) {
        m_statusLabel->setText("No network devices found");
    } else {
        m_statusLabel->setText(
            QString("Found %1 network device(s)").arg(deviceCount));
    }
}