import QtQuick
import QtQuick.Controls
import Quickshell
import qs.Common
import qs.Modules.Network
import qs.Services
import qs.Widgets
import qs.Modals
import qs.Modals.Common
import "../../../Common/QmlUtils.js" as QmlUtils

Rectangle {
    id: root

    LayoutMirroring.enabled: I18n.isRtl
    LayoutMirroring.childrenInherit: true

    implicitHeight: {
        if (height > 0)
            return height;
        if (NetworkService.wifiToggling)
            return headerRow.height + hotspotContentHeight + wifiToggleContent.height + Theme.spacingM;
        if (NetworkService.wifiEnabled)
            return headerRow.height + hotspotContentHeight + wifiContent.height + Theme.spacingM;
        return headerRow.height + hotspotContentHeight + wifiOffContent.height + Theme.spacingM;
    }
    radius: Theme.cornerRadius
    color: Theme.nestedSurface
    border.color: Theme.outlineMedium
    border.width: Theme.layerOutlineWidth

    Component.onCompleted: {
        NetworkService.addRef();
    }

    Component.onDestruction: {
        NetworkService.removeRef();
    }

    property bool hasEthernetAvailable: (NetworkService.ethernetDevices?.length ?? 0) > 0
    property bool hasWifiAvailable: (NetworkService.wifiDevices?.length ?? 0) > 0
    property bool hasBothConnectionTypes: hasEthernetAvailable && hasWifiAvailable
    property int maxPinnedNetworks: 3
    readonly property int hotspotContentHeight: currentPreferenceIndex === 1 && NetworkService.hotspotAvailable ? 56 + Theme.spacingS : 0

    property var hotspotStartConfirm: ConfirmModal {}

    function explainHotspotNeedsWiFi() {
        ToastService.showError(I18n.tr("WiFi is disabled", "hotspot start error title"), I18n.tr("Enable WiFi before starting the hotspot.", "hotspot WiFi requirement message"));
    }

    function startHotspotWithConfirm() {
        if (!NetworkService.hotspotWouldDisconnectWifi) {
            NetworkService.startHotspot();
            return;
        }
        hotspotStartConfirm.showWithOptions({
            title: I18n.tr("Start Hotspot?", "hotspot start confirmation title"),
            message: I18n.tr("This will disconnect WiFi from \"%1\" — the radio can't host a hotspot and stay connected at the same time. Internet sharing will need another connection, such as Ethernet.", "hotspot WiFi disconnection confirmation message").arg(NetworkService.currentWifiSSID),
            confirmText: I18n.tr("Start", "hotspot start confirmation action"),
            onConfirm: () => NetworkService.startHotspot()
        });
    }

    function openHotspotSettings() {
        PopoutService.closeControlCenter();
        PopoutService.openSettingsWithTab("network_wifi");
    }

    function getPinnedNetworks() {
        const pins = CacheData.wifiNetworkPins || {};
        return QmlUtils.normalizePinList(pins["preferredWifi"]);
    }

    property int currentPreferenceIndex: {
        if (DMSService.apiVersion < 5)
            return 1;
        if (NetworkService.backend !== "networkmanager" || DMSService.apiVersion <= 10)
            return 1;
        if (!hasEthernetAvailable)
            return 1;
        if (!hasWifiAvailable)
            return 0;

        const pref = NetworkService.userPreference;
        switch (pref) {
        case "ethernet":
            return 0;
        case "wifi":
            return 1;
        default:
            return NetworkService.networkStatus === "ethernet" ? 0 : 1;
        }
    }

    Row {
        id: headerRow
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.top: parent.top
        anchors.leftMargin: Theme.spacingM
        anchors.rightMargin: Theme.spacingM
        anchors.topMargin: Theme.spacingS
        height: Math.max(headerLeft.implicitHeight, rightControls.implicitHeight) + Theme.spacingS * 2

        StyledText {
            id: headerLeft
            text: I18n.tr("Network")
            font.pixelSize: Theme.fontSizeLarge
            color: Theme.surfaceText
            font.weight: Font.Medium
            anchors.verticalCenter: parent.verticalCenter
        }

        Item {
            height: 1
            width: parent.width - headerLeft.width - rightControls.width
        }

        Row {
            id: rightControls
            anchors.verticalCenter: parent.verticalCenter
            spacing: Theme.spacingS

            DankDropdown {
                id: wifiDeviceDropdown
                anchors.verticalCenter: parent.verticalCenter
                visible: currentPreferenceIndex === 1 && (NetworkService.wifiDevices?.length ?? 0) > 1
                compactMode: true
                dropdownWidth: 120
                popupWidth: 160
                alignPopupRight: true

                options: {
                    const devices = NetworkService.wifiDevices;
                    if (!devices || devices.length === 0)
                        return [I18n.tr("Auto")];
                    return [I18n.tr("Auto")].concat(devices.map(d => d.name));
                }

                currentValue: NetworkService.wifiDeviceOverride || I18n.tr("Auto")

                onValueChanged: value => {
                    const deviceName = value === I18n.tr("Auto") ? "" : value;
                    NetworkService.setWifiDeviceOverride(deviceName);
                }
            }

            DankButtonGroup {
                id: preferenceControls
                anchors.verticalCenter: parent.verticalCenter
                visible: hasBothConnectionTypes && NetworkService.backend === "networkmanager" && DMSService.apiVersion > 10
                buttonHeight: 28
                textSize: Theme.fontSizeSmall

                model: [I18n.tr("Ethernet"), I18n.tr("WiFi")]
                currentIndex: currentPreferenceIndex
                selectionMode: "single"
                onSelectionChanged: (index, selected) => {
                    if (!selected)
                        return;
                    NetworkService.setNetworkPreference(index === 0 ? "ethernet" : "wifi");
                }
            }

            DankActionButton {
                anchors.verticalCenter: parent.verticalCenter
                iconName: "settings"
                buttonSize: 28
                iconSize: 16
                iconColor: Theme.surfaceVariantText
                onClicked: {
                    PopoutService.closeControlCenter();
                    PopoutService.openSettingsWithTab(currentPreferenceIndex === 0 ? "network_ethernet" : "network_wifi");
                }
            }
        }
    }

    Item {
        id: hotspotRow
        anchors.top: headerRow.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: Theme.spacingM
        anchors.topMargin: Theme.spacingM
        visible: currentPreferenceIndex === 1 && NetworkService.hotspotAvailable
        height: visible ? 56 : 0

        Rectangle {
            anchors.fill: parent
            radius: Theme.cornerRadius
            color: hotspotMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceLight
            border.width: NetworkService.hotspotEnabled ? 2 : 1
            border.color: NetworkService.hotspotEnabled ? Theme.primary : Theme.outlineLight

            Row {
                anchors.left: parent.left
                anchors.leftMargin: Theme.spacingM
                anchors.right: hotspotRightControls.left
                anchors.rightMargin: Theme.spacingS
                anchors.verticalCenter: parent.verticalCenter
                spacing: Theme.spacingS

                DankIcon {
                    name: NetworkService.hotspotEnabled ? "wifi_tethering" : "wifi_tethering_off"
                    size: Theme.iconSize - 4
                    color: NetworkService.hotspotEnabled ? Theme.primary : Theme.surfaceText
                    anchors.verticalCenter: parent.verticalCenter
                }

                Column {
                    id: hotspotTextColumn

                    readonly property bool warnsWifiDrop: NetworkService.hotspotConfigured && NetworkService.wifiEnabled && !NetworkService.hotspotBusy && !NetworkService.hotspotActivating && !NetworkService.hotspotEnabled && NetworkService.hotspotWouldDisconnectWifi

                    anchors.verticalCenter: parent.verticalCenter
                    spacing: 2
                    width: parent.width - Theme.iconSize - Theme.spacingS

                    StyledText {
                        text: NetworkService.hotspotConfigured ? I18n.tr("Hotspot", "hotspot control label") : I18n.tr("Set up hotspot", "hotspot setup action label")
                        font.pixelSize: Theme.fontSizeMedium
                        font.weight: NetworkService.hotspotEnabled ? Font.Medium : Font.Normal
                        color: NetworkService.hotspotEnabled ? Theme.primary : Theme.surfaceText
                        elide: Text.ElideRight
                        width: parent.width
                    }

                    StyledText {
                        visible: !hotspotTextColumn.warnsWifiDrop
                        text: {
                            if (!NetworkService.hotspotConfigured)
                                return I18n.tr("Set up hotspot in Settings", "unconfigured hotspot status message");
                            if (NetworkService.hotspotBusy || NetworkService.hotspotActivating)
                                return I18n.tr("Starting...", "hotspot activation status");
                            if (NetworkService.hotspotEnabled)
                                return NetworkService.hotspotSSID || I18n.tr("Running", "hotspot active status");
                            if (!NetworkService.wifiEnabled)
                                return I18n.tr("WiFi disabled", "hotspot unavailable status");
                            return NetworkService.hotspotSSID || I18n.tr("Ready", "hotspot ready status");
                        }
                        font.pixelSize: Theme.fontSizeSmall
                        color: NetworkService.hotspotEnabled ? Theme.primary : Theme.surfaceVariantText
                        elide: Text.ElideRight
                        width: parent.width
                    }

                    Row {
                        visible: hotspotTextColumn.warnsWifiDrop
                        width: parent.width
                        spacing: Theme.spacingXS

                        StyledText {
                            id: hotspotWarnSsid
                            text: NetworkService.hotspotSSID || I18n.tr("Ready", "hotspot ready status")
                            font.pixelSize: Theme.fontSizeSmall
                            color: Theme.surfaceVariantText
                            elide: Text.ElideRight
                            width: Math.min(implicitWidth, parent.width / 2)
                        }

                        StyledText {
                            id: hotspotWarnSeparator
                            text: "•"
                            font.pixelSize: Theme.fontSizeSmall
                            color: Theme.surfaceVariantText
                        }

                        StyledText {
                            text: I18n.tr("Will disconnect \"%1\"", "hotspot WiFi disconnection warning").arg(NetworkService.currentWifiSSID)
                            font.pixelSize: Theme.fontSizeSmall
                            color: Theme.warning
                            elide: Text.ElideRight
                            width: Math.max(0, parent.width - hotspotWarnSsid.width - hotspotWarnSeparator.width - Theme.spacingXS * 2)
                        }
                    }
                }
            }

            Row {
                id: hotspotRightControls
                anchors.right: parent.right
                anchors.rightMargin: Theme.spacingM
                anchors.verticalCenter: parent.verticalCenter
                spacing: Theme.spacingS

                StyledText {
                    text: I18n.tr("Setup", "hotspot setup action")
                    font.pixelSize: Theme.fontSizeSmall
                    color: Theme.primary
                    visible: !NetworkService.hotspotConfigured
                    anchors.verticalCenter: parent.verticalCenter
                }

                DankIcon {
                    name: "chevron_right"
                    size: 20
                    color: Theme.primary
                    visible: !NetworkService.hotspotConfigured
                    anchors.verticalCenter: parent.verticalCenter
                }

                DankSpinner {
                    readonly property bool hotspotWorking: NetworkService.hotspotBusy || NetworkService.hotspotActivating
                    size: 20
                    strokeWidth: 2
                    color: Theme.primary
                    running: hotspotWorking
                    visible: NetworkService.hotspotConfigured && hotspotWorking
                    anchors.verticalCenter: parent.verticalCenter
                }

                DankToggle {
                    readonly property bool hotspotWorking: NetworkService.hotspotBusy || NetworkService.hotspotActivating
                    checked: NetworkService.hotspotEnabled
                    enabled: NetworkService.hotspotConfigured && !hotspotWorking
                    visible: NetworkService.hotspotConfigured && !hotspotWorking
                    onToggled: checked => {
                        if (checked) {
                            if (!NetworkService.wifiEnabled) {
                                root.explainHotspotNeedsWiFi();
                                return;
                            }
                            root.startHotspotWithConfirm();
                        } else {
                            NetworkService.stopHotspot();
                        }
                    }
                }
            }

            DankRipple {
                id: hotspotRipple
                cornerRadius: parent.radius
            }

            MouseArea {
                id: hotspotMouseArea
                anchors.fill: parent
                hoverEnabled: true
                cursorShape: Qt.PointingHandCursor
                enabled: !NetworkService.hotspotConfigured
                visible: !NetworkService.hotspotConfigured
                onPressed: mouse => hotspotRipple.trigger(mouse.x, mouse.y)
                onClicked: root.openHotspotSettings()
            }
        }
    }

    Item {
        id: wifiToggleContent
        anchors.top: hotspotRow.visible ? hotspotRow.bottom : headerRow.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: Theme.spacingM
        anchors.topMargin: hotspotRow.visible ? Theme.spacingS : Theme.spacingM
        visible: currentPreferenceIndex === 1 && NetworkService.wifiToggling
        height: visible ? wifiToggleColumn.implicitHeight + Theme.spacingM * 2 : 0

        Column {
            id: wifiToggleColumn
            anchors.centerIn: parent
            spacing: Theme.spacingM

            DankIcon {
                anchors.horizontalCenter: parent.horizontalCenter
                name: "sync"
                size: 32
                color: Theme.primary
                smoothTransform: NetworkService.wifiToggling

                RotationAnimator on rotation {
                    running: NetworkService.wifiToggling
                    loops: Animation.Infinite
                    from: 0
                    to: 360
                    duration: 1000
                }
            }

            StyledText {
                anchors.horizontalCenter: parent.horizontalCenter
                text: NetworkService.wifiEnabled ? I18n.tr("Disabling WiFi...") : I18n.tr("Enabling WiFi...")
                font.pixelSize: Theme.fontSizeMedium
                color: Theme.surfaceText
                horizontalAlignment: Text.AlignHCenter
            }
        }
    }

    Item {
        id: wifiOffContent
        anchors.top: hotspotRow.visible ? hotspotRow.bottom : headerRow.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: Theme.spacingM
        anchors.topMargin: hotspotRow.visible ? Theme.spacingS : Theme.spacingM
        visible: currentPreferenceIndex === 1 && !NetworkService.wifiEnabled && !NetworkService.wifiToggling
        height: visible ? wifiOffColumn.implicitHeight + Theme.spacingM * 2 : 0

        Column {
            id: wifiOffColumn
            anchors.centerIn: parent
            spacing: Theme.spacingL
            width: parent.width

            DankIcon {
                anchors.horizontalCenter: parent.horizontalCenter
                name: "wifi_off"
                size: 48
                color: Theme.surfaceTextSecondary
            }

            StyledText {
                anchors.horizontalCenter: parent.horizontalCenter
                text: I18n.tr("WiFi is off")
                font.pixelSize: Theme.fontSizeLarge
                color: Theme.surfaceText
                font.weight: Font.Medium
                horizontalAlignment: Text.AlignHCenter
            }

            Rectangle {
                anchors.horizontalCenter: parent.horizontalCenter
                width: enableWifiLabel.implicitWidth + Theme.spacingL * 2
                height: enableWifiLabel.implicitHeight + Theme.spacingM * 2
                radius: height / 2
                color: enableWifiButton.containsMouse ? Theme.primaryHover : Theme.primaryHoverLight
                border.width: 0
                border.color: Theme.primary

                StyledText {
                    id: enableWifiLabel
                    anchors.centerIn: parent
                    text: I18n.tr("Enable WiFi")
                    color: Theme.primary
                    font.pixelSize: Theme.fontSizeMedium
                    font.weight: Font.Medium
                }

                MouseArea {
                    id: enableWifiButton
                    anchors.fill: parent
                    hoverEnabled: true
                    cursorShape: Qt.PointingHandCursor
                    onClicked: NetworkService.toggleWifiRadio()
                }
            }
        }
    }

    ScriptModel {
        id: wiredConnectionsModel
        objectProp: "uuid"
        values: {
            const networks = NetworkService.wiredConnections;
            if (!networks)
                return [];
            let sorted = [...networks];
            sorted.sort((a, b) => {
                if (a.isActive && !b.isActive)
                    return -1;
                if (!a.isActive && b.isActive)
                    return 1;
                return a.id.localeCompare(b.id);
            });
            return sorted;
        }
    }

    DankFlickable {
        id: wiredContent
        anchors.top: headerRow.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.margins: Theme.spacingM
        anchors.topMargin: Theme.spacingM
        visible: currentPreferenceIndex === 0 && NetworkService.backend === "networkmanager" && DMSService.apiVersion > 10
        contentHeight: wiredColumn.height
        clip: true

        Column {
            id: wiredColumn
            width: parent.width
            spacing: Theme.spacingS

            Repeater {
                model: wiredConnectionsModel

                delegate: Rectangle {
                    id: wiredDelegate
                    required property var modelData
                    required property int index

                    readonly property bool isActive: modelData.isActive
                    readonly property string configName: modelData.id || I18n.tr("Unknown Config")

                    width: parent.width
                    height: wiredContentRow.implicitHeight + Theme.spacingM * 2
                    radius: Theme.cornerRadius
                    color: wiredNetworkMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceLight
                    border.color: isActive ? Theme.primary : Theme.outlineLight
                    border.width: isActive ? 2 : 1

                    Row {
                        id: wiredContentRow
                        anchors.left: parent.left
                        anchors.verticalCenter: parent.verticalCenter
                        anchors.leftMargin: Theme.spacingM
                        spacing: Theme.spacingS

                        DankIcon {
                            name: "lan"
                            size: Theme.iconSize - 4
                            color: wiredDelegate.isActive ? Theme.primary : Theme.surfaceText
                            anchors.verticalCenter: parent.verticalCenter
                        }

                        Column {
                            anchors.verticalCenter: parent.verticalCenter
                            width: 200

                            StyledText {
                                text: wiredDelegate.configName
                                font.pixelSize: Theme.fontSizeMedium
                                color: wiredDelegate.isActive ? Theme.primary : Theme.surfaceText
                                font.weight: wiredDelegate.isActive ? Font.Medium : Font.Normal
                                elide: Text.ElideRight
                                width: parent.width
                            }
                        }
                    }

                    DankActionButton {
                        id: wiredOptionsButton
                        anchors.right: parent.right
                        anchors.rightMargin: Theme.spacingS
                        anchors.verticalCenter: parent.verticalCenter
                        iconName: "more_horiz"
                        buttonSize: 28
                        onClicked: {
                            if (wiredNetworkContextMenu.visible) {
                                wiredNetworkContextMenu.close();
                                return;
                            }
                            wiredNetworkContextMenu.currentID = modelData.id;
                            wiredNetworkContextMenu.currentUUID = modelData.uuid;
                            wiredNetworkContextMenu.currentConnected = wiredDelegate.isActive;
                            wiredNetworkContextMenu.popup(wiredOptionsButton, -wiredNetworkContextMenu.width + wiredOptionsButton.width, wiredOptionsButton.height + Theme.spacingXS);
                        }
                    }

                    DankRipple {
                        id: wiredRipple
                        cornerRadius: parent.radius
                    }

                    MouseArea {
                        id: wiredNetworkMouseArea
                        anchors.fill: parent
                        anchors.rightMargin: wiredOptionsButton.width + Theme.spacingS
                        hoverEnabled: true
                        cursorShape: Qt.PointingHandCursor
                        onPressed: mouse => wiredRipple.trigger(mouse.x, mouse.y)
                        onClicked: function (event) {
                            if (modelData.uuid !== NetworkService.ethernetConnectionUuid)
                                NetworkService.connectToSpecificWiredConfig(modelData.uuid);
                            event.accepted = true;
                        }
                    }
                }
            }
        }
    }

    Menu {
        id: wiredNetworkContextMenu
        width: 150
        closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent

        property string currentID: ""
        property string currentUUID: ""
        property bool currentConnected: false

        background: Rectangle {
            color: BlurService.enabled ? Theme.surfaceContainer : Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
            radius: Theme.cornerRadius
            border.width: 0
            border.color: Theme.outlineStrong
        }

        MenuItem {
            text: I18n.tr("Activate")
            height: !wiredNetworkContextMenu.currentConnected ? 32 : 0
            visible: !wiredNetworkContextMenu.currentConnected

            contentItem: StyledText {
                text: parent.text
                font.pixelSize: Theme.fontSizeSmall
                color: Theme.surfaceText
                leftPadding: Theme.spacingS
                verticalAlignment: Text.AlignVCenter
            }

            background: Rectangle {
                color: parent.hovered ? Theme.primaryHoverLight : Theme.withAlpha(Theme.primaryHoverLight, 0)
                radius: Theme.cornerRadius / 2
            }

            onTriggered: {
                if (!wiredNetworkContextMenu.currentConnected)
                    NetworkService.connectToSpecificWiredConfig(wiredNetworkContextMenu.currentUUID);
            }
        }

        MenuItem {
            text: I18n.tr("Disconnect")
            height: wiredNetworkContextMenu.currentConnected ? 32 : 0
            visible: wiredNetworkContextMenu.currentConnected

            contentItem: StyledText {
                text: parent.text
                font.pixelSize: Theme.fontSizeSmall
                color: Theme.error
                leftPadding: Theme.spacingS
                verticalAlignment: Text.AlignVCenter
            }

            background: Rectangle {
                color: parent.hovered ? Theme.errorHover : Theme.withAlpha(Theme.errorHover, 0)
                radius: Theme.cornerRadius / 2
            }

            onTriggered: {
                NetworkService.toggleNetworkConnection("ethernet");
            }
        }

        MenuItem {
            text: I18n.tr("Network Info")
            height: wiredNetworkContextMenu.currentConnected ? 32 : 0
            visible: wiredNetworkContextMenu.currentConnected

            contentItem: StyledText {
                text: parent.text
                font.pixelSize: Theme.fontSizeSmall
                color: Theme.surfaceText
                leftPadding: Theme.spacingS
                verticalAlignment: Text.AlignVCenter
            }

            background: Rectangle {
                color: parent.hovered ? Theme.primaryHoverLight : Theme.withAlpha(Theme.primaryHoverLight, 0)
                radius: Theme.cornerRadius / 2
            }

            onTriggered: {
                const networkData = NetworkService.getWiredNetworkInfo(wiredNetworkContextMenu.currentUUID);
                networkWiredInfoModalLoader.active = true;
                networkWiredInfoModalLoader.item.showNetworkInfo(wiredNetworkContextMenu.currentID, networkData);
            }
        }
    }

    ScriptModel {
        id: wifiNetworksModel
        objectProp: "ssid"
        values: wifiContent.menuOpen ? wifiContent.frozenNetworks : wifiContent.sortedNetworks
    }

    Item {
        id: wifiScanningOverlay
        anchors.top: hotspotRow.visible ? hotspotRow.bottom : headerRow.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.margins: Theme.spacingM
        anchors.topMargin: hotspotRow.visible ? Theme.spacingS : Theme.spacingM
        visible: currentPreferenceIndex === 1 && NetworkService.wifiEnabled && !NetworkService.wifiToggling && NetworkService.wifiInterface && (NetworkService.wifiNetworks?.length ?? 0) < 1 && NetworkService.isScanning

        DankIcon {
            anchors.centerIn: parent
            name: "refresh"
            size: 48
            color: Theme.surfaceTextAlpha
            smoothTransform: wifiScanningOverlay.visible

            RotationAnimator on rotation {
                running: wifiScanningOverlay.visible
                loops: Animation.Infinite
                from: 0
                to: 360
                duration: 1000
            }
        }
    }

    DankListView {
        id: wifiContent
        anchors.top: hotspotRow.visible ? hotspotRow.bottom : headerRow.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.margins: Theme.spacingM
        anchors.topMargin: hotspotRow.visible ? Theme.spacingS : Theme.spacingM
        visible: currentPreferenceIndex === 1 && NetworkService.wifiEnabled && !NetworkService.wifiToggling && !wifiScanningOverlay.visible
        clip: true
        spacing: Theme.spacingS
        model: wifiNetworksModel

        property var frozenNetworks: []
        property bool menuOpen: false
        property var sortedNetworks: {
            const ssid = NetworkService.currentWifiSSID;
            const networks = NetworkService.wifiNetworks;
            const pinnedList = root.getPinnedNetworks();

            let sorted = [...networks];
            sorted.sort((a, b) => {
                const aPinnedIndex = pinnedList.indexOf(a.ssid);
                const bPinnedIndex = pinnedList.indexOf(b.ssid);
                if (aPinnedIndex !== -1 || bPinnedIndex !== -1) {
                    if (aPinnedIndex === -1)
                        return 1;
                    if (bPinnedIndex === -1)
                        return -1;
                    return aPinnedIndex - bPinnedIndex;
                }
                if (a.ssid === ssid)
                    return -1;
                if (b.ssid === ssid)
                    return 1;
                const aBucket = Math.floor((a.signal || 0) / 25);
                const bBucket = Math.floor((b.signal || 0) / 25);
                if (aBucket !== bBucket)
                    return bBucket - aBucket;
                return (a.ssid || "").localeCompare(b.ssid || "");
            });
            return sorted;
        }
        onSortedNetworksChanged: {
            if (!menuOpen)
                frozenNetworks = sortedNetworks;
        }
        onMenuOpenChanged: {
            if (menuOpen)
                frozenNetworks = sortedNetworks;
        }

        delegate: Rectangle {
            id: wifiDelegate
            required property var modelData
            required property int index

            readonly property bool isConnected: modelData.ssid === NetworkService.currentWifiSSID
            readonly property bool isConnecting: NetworkService.isWifiConnecting && NetworkService.connectingSSID === modelData.ssid
            readonly property bool isPinned: root.getPinnedNetworks().includes(modelData.ssid)
            readonly property string networkName: modelData.ssid || I18n.tr("Unknown Network")
            readonly property int signalStrength: modelData.signal || 0

            width: wifiContent.width
            height: wifiContentRow.implicitHeight + Theme.spacingM * 2
            radius: Theme.cornerRadius
            color: networkMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceLight
            border.color: wifiDelegate.isConnected ? Theme.primary : Theme.outlineLight
            border.width: wifiDelegate.isConnected ? 2 : 1

            Row {
                id: wifiContentRow
                anchors.left: parent.left
                anchors.verticalCenter: parent.verticalCenter
                anchors.leftMargin: Theme.spacingM
                spacing: Theme.spacingS

                DankSpinner {
                    size: Theme.iconSize - 4
                    strokeWidth: 2
                    color: Theme.warning
                    running: wifiDelegate.isConnecting
                    visible: wifiDelegate.isConnecting
                    anchors.verticalCenter: parent.verticalCenter
                }

                DankIcon {
                    visible: !wifiDelegate.isConnecting
                    name: {
                        if (wifiDelegate.signalStrength >= 50)
                            return "wifi";
                        if (wifiDelegate.signalStrength >= 25)
                            return "wifi_2_bar";
                        return "wifi_1_bar";
                    }
                    size: Theme.iconSize - 4
                    color: wifiDelegate.isConnected ? Theme.primary : Theme.surfaceText
                    anchors.verticalCenter: parent.verticalCenter
                }

                Column {
                    anchors.verticalCenter: parent.verticalCenter
                    width: 200

                    StyledText {
                        text: wifiDelegate.networkName
                        font.pixelSize: Theme.fontSizeMedium
                        color: wifiDelegate.isConnected ? Theme.primary : Theme.surfaceText
                        font.weight: wifiDelegate.isConnected ? Font.Medium : Font.Normal
                        elide: Text.ElideRight
                        width: parent.width
                    }

                    Row {
                        spacing: Theme.spacingXS

                        StyledText {
                            text: wifiDelegate.isConnecting ? I18n.tr("Connecting...") + " \u2022" : (wifiDelegate.isConnected ? I18n.tr("Connected") + " \u2022" : (modelData.secured ? I18n.tr("Secured") + " \u2022" : I18n.tr("Open", "network security type", true) + " \u2022"))
                            font.pixelSize: Theme.fontSizeSmall
                            color: wifiDelegate.isConnecting ? Theme.warning : Theme.surfaceVariantText
                        }

                        StyledText {
                            text: modelData.saved ? I18n.tr("Saved") : ""
                            font.pixelSize: Theme.fontSizeSmall
                            color: Theme.primary
                            visible: text.length > 0
                        }

                        StyledText {
                            text: (modelData.saved ? "\u2022 " : "") + wifiDelegate.signalStrength + "%"
                            font.pixelSize: Theme.fontSizeSmall
                            color: Theme.surfaceVariantText
                        }
                    }
                }
            }

            DankActionButton {
                id: optionsButton
                anchors.right: parent.right
                anchors.rightMargin: Theme.spacingS
                anchors.verticalCenter: parent.verticalCenter
                iconName: "more_horiz"
                buttonSize: 28
                onClicked: {
                    if (networkContextMenu.visible) {
                        networkContextMenu.close();
                        return;
                    }
                    wifiContent.menuOpen = true;
                    networkContextMenu.currentSSID = modelData.ssid;
                    networkContextMenu.currentSecured = modelData.secured;
                    networkContextMenu.currentEnterprise = modelData.enterprise;
                    networkContextMenu.currentConnected = wifiDelegate.isConnected;
                    networkContextMenu.currentConnecting = wifiDelegate.isConnecting;
                    networkContextMenu.currentSaved = modelData.saved;
                    networkContextMenu.currentSignal = modelData.signal;
                    networkContextMenu.currentAutoconnect = modelData.autoconnect || false;
                    networkContextMenu.popup(optionsButton, -networkContextMenu.width + optionsButton.width, optionsButton.height + Theme.spacingXS);
                }
            }

            Rectangle {
                id: pinButton
                anchors.right: parent.right
                anchors.rightMargin: optionsButton.width + Theme.spacingM + Theme.spacingS
                anchors.verticalCenter: parent.verticalCenter
                width: pinWifiRow.width + Theme.spacingS * 2
                height: pinWifiRow.implicitHeight + Theme.spacingXS * 2
                radius: height / 2
                color: wifiDelegate.isPinned ? Theme.primaryHover : Theme.withAlpha(Theme.surfaceText, 0.05)

                Row {
                    id: pinWifiRow
                    anchors.centerIn: parent
                    spacing: Theme.spacingXS

                    DankIcon {
                        name: "push_pin"
                        size: 16
                        color: wifiDelegate.isPinned ? Theme.primary : Theme.surfaceText
                        anchors.verticalCenter: parent.verticalCenter
                    }

                    StyledText {
                        text: wifiDelegate.isPinned ? I18n.tr("Pinned") : I18n.tr("Pin")
                        font.pixelSize: Theme.fontSizeSmall
                        color: wifiDelegate.isPinned ? Theme.primary : Theme.surfaceText
                        anchors.verticalCenter: parent.verticalCenter
                    }
                }

                DankRipple {
                    id: pinRipple
                    cornerRadius: parent.radius
                }

                MouseArea {
                    anchors.fill: parent
                    cursorShape: Qt.PointingHandCursor
                    onPressed: mouse => pinRipple.trigger(mouse.x, mouse.y)
                    onClicked: {
                        const pins = JSON.parse(JSON.stringify(CacheData.wifiNetworkPins || {}));
                        let pinnedList = QmlUtils.normalizePinList(pins["preferredWifi"]);
                        const pinIndex = pinnedList.indexOf(modelData.ssid);

                        if (pinIndex !== -1) {
                            pinnedList.splice(pinIndex, 1);
                        } else {
                            pinnedList.unshift(modelData.ssid);
                            if (pinnedList.length > root.maxPinnedNetworks)
                                pinnedList = pinnedList.slice(0, root.maxPinnedNetworks);
                        }

                        if (pinnedList.length > 0)
                            pins["preferredWifi"] = pinnedList;
                        else
                            delete pins["preferredWifi"];

                        CacheData.set("wifiNetworkPins", pins);
                    }
                }
            }

            DankActionButton {
                id: qrCodeButton
                visible: modelData.secured && modelData.saved && !(modelData.enterprise || false)
                anchors.right: parent.right
                anchors.rightMargin: optionsButton.width + pinWifiRow.width + 3 * Theme.spacingM + Theme.spacingS
                anchors.verticalCenter: parent.verticalCenter
                iconName: "qr_code"
                buttonSize: 28
                onClicked: {
                    PopoutService.showWifiQRCodeModal(modelData.ssid);
                }
            }

            DankRipple {
                id: wifiRipple
                cornerRadius: parent.radius
            }

            MouseArea {
                id: networkMouseArea
                anchors.fill: parent
                anchors.rightMargin: optionsButton.width + pinWifiRow.width + (qrCodeButton.visible ? qrCodeButton.width : 0) + Theme.spacingS * 5 + Theme.spacingM
                hoverEnabled: true
                enabled: !NetworkService.isWifiConnecting || wifiDelegate.isConnected
                cursorShape: enabled ? Qt.PointingHandCursor : Qt.BusyCursor
                onPressed: mouse => wifiRipple.trigger(mouse.x, mouse.y)
                onClicked: function (event) {
                    if (wifiDelegate.isConnected) {
                        event.accepted = true;
                        return;
                    }
                    WifiConnectionActions.connectToNetwork(modelData, {
                        connected: wifiDelegate.isConnected
                    });
                    event.accepted = true;
                }
            }
        }
    }

    Menu {
        id: networkContextMenu
        width: 150
        closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent

        property string currentSSID: ""
        property bool currentSecured: false
        property bool currentEnterprise: false
        property bool currentConnected: false
        property bool currentConnecting: false
        property bool currentSaved: false
        property int currentSignal: 0
        property bool currentAutoconnect: false

        readonly property bool showSavedOptions: currentSaved || currentConnected

        onClosed: {
            wifiContent.menuOpen = false;
        }

        background: Rectangle {
            color: BlurService.enabled ? Theme.surfaceContainer : Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
            radius: Theme.cornerRadius
            border.width: 0
            border.color: Theme.outlineStrong
        }

        MenuItem {
            text: networkContextMenu.currentConnecting ? I18n.tr("Connecting...") : (networkContextMenu.currentConnected ? I18n.tr("Disconnect") : I18n.tr("Connect"))
            height: 32
            enabled: !networkContextMenu.currentConnecting

            contentItem: StyledText {
                text: parent.text
                font.pixelSize: Theme.fontSizeSmall
                color: parent.enabled ? Theme.surfaceText : Theme.surfaceVariantText
                leftPadding: Theme.spacingS
                verticalAlignment: Text.AlignVCenter
            }

            background: Rectangle {
                color: parent.hovered ? Theme.primaryHoverLight : Theme.withAlpha(Theme.primaryHoverLight, 0)
                radius: Theme.cornerRadius / 2
            }

            onTriggered: {
                WifiConnectionActions.connectToNetworkFromDetails(networkContextMenu.currentSSID, networkContextMenu.currentSecured, networkContextMenu.currentSaved, networkContextMenu.currentEnterprise, networkContextMenu.currentConnected, {
                    disconnectWhenConnected: true
                });
            }
        }

        MenuItem {
            text: I18n.tr("Network Info")
            height: 32

            contentItem: StyledText {
                text: parent.text
                font.pixelSize: Theme.fontSizeSmall
                color: Theme.surfaceText
                leftPadding: Theme.spacingS
                verticalAlignment: Text.AlignVCenter
            }

            background: Rectangle {
                color: parent.hovered ? Theme.primaryHoverLight : Theme.withAlpha(Theme.primaryHoverLight, 0)
                radius: Theme.cornerRadius / 2
            }

            onTriggered: {
                const networkData = NetworkService.getNetworkInfo(networkContextMenu.currentSSID);
                networkInfoModalLoader.active = true;
                networkInfoModalLoader.item.showNetworkInfo(networkContextMenu.currentSSID, networkData);
            }
        }

        MenuItem {
            text: networkContextMenu.currentAutoconnect ? I18n.tr("Disable Autoconnect") : I18n.tr("Enable Autoconnect")
            height: networkContextMenu.showSavedOptions && DMSService.apiVersion > 13 ? 32 : 0
            visible: networkContextMenu.showSavedOptions && DMSService.apiVersion > 13

            contentItem: StyledText {
                text: parent.text
                font.pixelSize: Theme.fontSizeSmall
                color: Theme.surfaceText
                leftPadding: Theme.spacingS
                verticalAlignment: Text.AlignVCenter
            }

            background: Rectangle {
                color: parent.hovered ? Theme.primaryHoverLight : Theme.withAlpha(Theme.primaryHoverLight, 0)
                radius: Theme.cornerRadius / 2
            }

            onTriggered: {
                NetworkService.setWifiAutoconnect(networkContextMenu.currentSSID, !networkContextMenu.currentAutoconnect);
            }
        }

        MenuItem {
            text: I18n.tr("Forget Network")
            height: networkContextMenu.showSavedOptions ? 32 : 0
            visible: networkContextMenu.showSavedOptions

            contentItem: StyledText {
                text: parent.text
                font.pixelSize: Theme.fontSizeSmall
                color: Theme.error
                leftPadding: Theme.spacingS
                verticalAlignment: Text.AlignVCenter
            }

            background: Rectangle {
                color: parent.hovered ? Theme.errorHover : Theme.withAlpha(Theme.errorHover, 0)
                radius: Theme.cornerRadius / 2
            }

            onTriggered: {
                NetworkService.forgetWifiNetwork(networkContextMenu.currentSSID);
            }
        }
    }

    Loader {
        id: networkInfoModalLoader
        active: false
        sourceComponent: NetworkInfoModal {}
    }

    Loader {
        id: networkWiredInfoModalLoader
        active: false
        sourceComponent: NetworkWiredInfoModal {}
    }
}
