
(deflisten netinfo
  :initial '{"wifi":{"ssid":"","ip":"","freq":0,"band":"","gen":"","signal":0},"ethernet":{"state":"down","ip":"","speed":"","interface":""},"usb":{"interface":"","ip":""}}'
  "scripts/net/netinfo")

(deflisten bt-devices
  :initial "[]"
  "scripts/net/bt-devices")

; --- Shared widgets ---

(defwidget netinfo-row [label value]
  (box :orientation "h" :space-evenly false :class "netinfo-row"
    (label :class "netinfo-label" :halign "start" :text label)
    (label :class "netinfo-value" :halign "end" :hexpand true :text value)))

(defwidget section-header-toggle [title accent enabled onclick icon-on icon-off]
  (box :orientation "h" :space-evenly false :valign "center" :class "sys-section-header"
    (box :class "section-accent ${accent}")
    (label :class "sys-label" :text title :hexpand true :halign "start")
    (button
      :class "net-toggle-btn ${enabled ? 'net-toggle-on' : 'net-toggle-off'}"
      :onclick onclick
      (label :text {enabled ? icon-on : icon-off}))))

; --- WiFi ---

(defwidget wifi-net-section []
  (box :orientation "v" :space-evenly false :class "sys-section"
    (section-header-toggle
      :title "WiFi" :accent "wifi-accent"
      :enabled {net.wifi.enabled}
      :onclick {net.wifi.enabled ? "rfkill block wlan" : "rfkill unblock wlan"}
      :icon-on "󰤨" :icon-off "󰖪")
    (box :orientation "v" :space-evenly false
      :visible {net.wifi.connected}
      (netinfo-row :label "SSID"   :value {netinfo.wifi.ssid})
      (netinfo-row :label "IP"     :value {netinfo.wifi.ip})
      (netinfo-row :label "Signal" :value "${net.wifi.icon}  ${netinfo.wifi.signal} dBm")
      (netinfo-row :label "Freq"   :value "${netinfo.wifi.freq} MHz · ${netinfo.wifi.band} · ${netinfo.wifi.gen}"))
    (label :class "netinfo-dim" :halign "start"
      :visible {!net.wifi.connected}
      :text {net.wifi.enabled ? "Not connected" : "Disabled"})))

; --- USB ---

(defwidget usb-net-section []
  (box :orientation "v" :space-evenly false :class "sys-section"
    (section-header :title "USB" :accent "usb-accent")
    (netinfo-row :label "Interface" :value {netinfo.usb.interface})
    (netinfo-row :label "IP"        :value {netinfo.usb.ip})))

; --- Ethernet ---

(defwidget ethernet-net-section []
  (box :orientation "v" :space-evenly false :class "sys-section"
    (section-header :title "Ethernet" :accent "eth-accent")
    (box :orientation "v" :space-evenly false
      :visible {net.ethernet.connected}
      (netinfo-row :label "Interface" :value {netinfo.ethernet.interface})
      (netinfo-row :label "IP"        :value {netinfo.ethernet.ip})
      (netinfo-row :label "Speed"     :value {netinfo.ethernet.speed}))
    (label :class "netinfo-dim" :halign "start"
      :visible {!net.ethernet.connected}
      :text "No carrier")))

; --- Bluetooth ---

(defwidget bt-device-row [device]
  (box :orientation "h" :space-evenly false :class "bt-device-row" :valign "center"
    (label :class "bt-device-name" :hexpand true :halign "start" :text {device.name})
    (button
      :class "bt-device-btn ${device.connected ? 'bt-btn-on' : 'bt-btn-off'}"
      :onclick "scripts/net/bt-toggle ${device.mac}"
      :tooltip {device.connected ? "Disconnect" : "Connect"}
      (label :text {device.connected ? "󰂱" : "󰂯"}))))

(defwidget bluetooth-net-section []
  (box :orientation "v" :space-evenly false :class "sys-section"
    (section-header-toggle
      :title "Bluetooth" :accent "blt-accent"
      :enabled {bluetooth.powered}
      :onclick {bluetooth.powered ? "bluetoothctl power off" : "bluetoothctl power on"}
      :icon-on "󰂯" :icon-off "󰂲")
    (scroll :vscroll true :hscroll false :height 90
      :visible {bluetooth.powered}
      (box :orientation "v" :space-evenly false
        (for device in {bt-devices}
          (bt-device-row :device {device}))))
    (label :class "netinfo-dim" :halign "start"
      :visible {!bluetooth.powered}
      :text "Disabled")))

; --- Root ---

(defwidget net-win []
  (box :class "sys-win" :space-evenly false :orientation "v"
    (box :visible {net.usb.connected} :space-evenly false :orientation "v"
      (usb-net-section)
      (box :class "section-sep"))
    (ethernet-net-section)
    (box :class "section-sep")
    (wifi-net-section)
    (box :class "section-sep")
    (bluetooth-net-section)))
