// Network & Devices.
//
// Wi-Fi and Bluetooth are handled here rather than delegated. Everything goes
// through Quickshell.Networking and Quickshell.Bluetooth -- NetworkManager and
// BlueZ over DBus -- and nothing shells out to nmcli or bluetoothctl. That was
// the founding requirement for this desktop: never having to drop to a terminal
// to join a network.
//
// Scanning follows this page being on screen. Wi-Fi scanning and especially
// Bluetooth discovery hold the radio, and doing either for a list nobody is
// looking at is battery and airtime spent on nothing.

import QtQuick
import Quickshell
import Quickshell.Networking
import qs.config
import qs.services

SettingsPage {
    id: root


    title: "Network & Devices"
    lede: Connectivity.activeNetwork
        ? "Connected to " + Connectivity.activeNetwork.name
        : "Wi-Fi, Bluetooth, and the things Fedora owns."

    // Drive the scanners only while this page is the one being shown.
    Component.onCompleted: {
        Connectivity.active = true;
        if (!WifiShare.scanned)
            WifiShare.refresh();
    }
    Component.onDestruction: Connectivity.active = false

    SettingsCard {
        title: "Wired"
        visible: Connectivity.wiredDevice !== null

        TextRow {
            label: "Ethernet"
            detail: Connectivity.wiredDevice ? Connectivity.wiredDevice.name : ""
            value: Connectivity.wiredDevice && Connectivity.wiredDevice.connected ? "Connected" : "Not connected"
            divider: false
        }
    }

    SettingsCard {
        title: "Wi-Fi"
        // A Wi-Fi switch reading "On" above the words "No Wi-Fi adapter" is a
        // contradiction; with no radio the card simply does not belong.
        visible: Connectivity.wifiDevice !== null
        subtitle: "Networks are re-scanned while this page is open."

        SettingRow {
            label: "Wi-Fi"
            detail: Connectivity.wifiEnabled ? "On" : "Off"
            controlWidth: 48
            divider: Connectivity.wifiEnabled

            SettingsToggle {
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                checked: Connectivity.wifiEnabled
                enabled: Connectivity.wifiAvailable
                onToggled: value => Networking.wifiEnabled = value
            }
        }

        WifiPanel {
            width: parent.width
            visible: Connectivity.wifiEnabled
        }
    }

    // Sharing a network by QR, the way GNOME's Wi-Fi panel does. The
    // alternative is reading a passphrase out loud.
    //
    // The image holds the password in machine-readable form, so it is generated
    // on demand rather than up front, and the helper writes it to tmpfs under
    // XDG_RUNTIME_DIR instead of anywhere persistent.
    SettingsCard {
        visible: Connectivity.wifiDevice !== null && WifiShare.shareable.length > 0
        title: "Share a network"
        subtitle: WifiShare.sharing !== ""
            ? "Point a phone's camera at the code to join " + WifiShare.sharing + "."
            : "Shows a QR code a phone can scan to join, without reading the password out."

        Repeater {
            model: WifiShare.shareable

            ActionRow {
                id: shareRow
                required property var modelData
                required property int index

                label: shareRow.modelData.ssid
                detail: WifiShare.sharing === shareRow.modelData.name
                    ? "Showing a code below — anyone who can see the screen can join"
                    : "Saved network"
                action: WifiShare.sharing === shareRow.modelData.name ? "Hide" : "Show code"
                divider: shareRow.index < WifiShare.shareable.length - 1 || WifiShare.sharing !== ""
                onTriggered: WifiShare.sharing === shareRow.modelData.name
                    ? WifiShare.stopSharing()
                    : WifiShare.share(shareRow.modelData.name)
            }
        }

        // Drawn at its natural size on a white plate: a QR code inverted or
        // tinted to match a dark theme is unreliable to scan, and this one has
        // exactly one job.
        Item {
            width: parent.width
            visible: WifiShare.sharing !== "" && WifiShare.imagePath !== ""
            implicitHeight: visible ? plate.height + 20 : 0

            Rectangle {
                id: plate
                anchors.horizontalCenter: parent.horizontalCenter
                y: 10
                width: 208
                height: 208
                radius: 10
                color: "white"

                Image {
                    anchors.centerIn: parent
                    width: 184
                    height: 184
                    smooth: false
                    fillMode: Image.PreserveAspectFit
                    cache: false
                    source: WifiShare.imagePath !== "" ? "file://" + WifiShare.imagePath : ""
                }
            }
        }
    }

    SettingsCard {
        title: "Bluetooth"
        visible: Connectivity.adapter !== null
        subtitle: "Discovery runs while this page is open."

        SettingRow {
            label: "Bluetooth"
            detail: Connectivity.adapter
                ? (Connectivity.adapter.enabled ? "On" : "Off")
                : "Unavailable"
            controlWidth: 48
            divider: !!(Connectivity.adapter && Connectivity.adapter.enabled)

            SettingsToggle {
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                checked: !!(Connectivity.adapter && Connectivity.adapter.enabled)
                enabled: Connectivity.adapter !== null
                onToggled: value => {
                    if (Connectivity.adapter)
                        Connectivity.adapter.enabled = value;
                }
            }
        }

        BluetoothPanel {
            width: parent.width
            visible: !!(Connectivity.adapter && Connectivity.adapter.enabled)
        }
    }

    SettingsCard {
        title: "Owned by Fedora"
        subtitle: "VPNs, per-connection routing, printers, and online accounts are configured by GNOME's panels, which are installed and searchable."

        ActionRow {
            label: "Network connections"
            detail: "VPN, proxies, and per-connection settings"
            action: "Open"
            onTriggered: SystemSettings.openGnomePanel("network")
        }
        ActionRow {
            label: "Printers"
            action: "Open"
            onTriggered: SystemSettings.openGnomePanel("printers")
        }
        ActionRow {
            label: "Online accounts"
            action: "Open"
            divider: false
            onTriggered: SystemSettings.openGnomePanel("online-accounts")
        }
    }
}
