{
  outputs,
  config,
  lib,
  pkgs,
  ...
}: let
  # Dependencies
  cat = "${pkgs.coreutils}/bin/cat";
  cut = "${pkgs.coreutils}/bin/cut";
  find = "${pkgs.findutils}/bin/find";
  grep = "${pkgs.gnugrep}/bin/grep";
  perl = "${pkgs.perl}/bin/perl";
  pgrep = "${pkgs.procps}/bin/pgrep";
  sed = "${pkgs.gnused}/bin/sed";
  tail = "${pkgs.coreutils}/bin/tail";
  wc = "${pkgs.coreutils}/bin/wc";
  xargs = "${pkgs.findutils}/bin/xargs";
  timeout = "${pkgs.coreutils}/bin/timeout";
  ping = "${pkgs.iputils}/bin/ping";

  jq = "${pkgs.jq}/bin/jq";
  xml = "${pkgs.xmlstarlet}/bin/xml";
  gamemoded = "${pkgs.gamemode}/bin/gamemoded";
  systemctl = "${pkgs.systemd}/bin/systemctl";
  journalctl = "${pkgs.systemd}/bin/journalctl";
  playerctl = "${pkgs.playerctl}/bin/playerctl";
  playerctld = "${pkgs.playerctl}/bin/playerctld";
  pavucontrol = "${pkgs.pavucontrol}/bin/pavucontrol";
  khal = "${pkgs.khal}/bin/khal";
  python = "${pkgs.python3}/bin/python3";

  # Function to simplify making waybar outputs
  jsonOutput = name: {
    pre ? "",
    text ? "",
    tooltip ? "",
    alt ? "",
    class ? "",
    percentage ? "",
  }: "${pkgs.writeShellScriptBin "waybar-${name}" ''
    set -euo pipefail
    ${pre}
    ${jq} -cn \
      --arg text "${text}" \
      --arg tooltip "${tooltip}" \
      --arg alt "${alt}" \
      --arg class "${class}" \
      --arg percentage "${percentage}" \
      '{text:$text,tooltip:$tooltip,alt:$alt,class:$class,percentage:$percentage}'
  ''}/bin/waybar-${name}";
in {
  programs.waybar = {
    enable = true;
    package = pkgs.waybar.overrideAttrs (oa: {
      mesonFlags = (oa.mesonFlags or []) ++ ["-Dexperimental=true"];
    });
    systemd.enable = true;
    settings = {
      primary = {
        layer = "top";
        height = 40;
        margin = "6";
        position = "top";
        modules-left =
          [
            "custom/currentplayer"
            "custom/player"
          ]
          ++ (lib.optionals config.wayland.windowManager.sway.enable [
            "sway/workspaces"
            "sway/mode"
          ])
          ++ (lib.optionals config.wayland.windowManager.hyprland.enable [
            "hyprland/workspaces"
            "hyprland/submap"
          ])
          ++ [
            "custom/events"
          ];
        modules-center = [
          "cpu"
          "custom/gpu"
          "memory"
          "clock"
          "pulseaudio"
          # TODO: check if the following modules are useful to me
          # "custom/unread-mail"
          # "custom/gammastep"
          # "custom/gpg-agent"
        ];
        modules-right = [
          "network"
          # TODO: check if the following modules are useful to me
          # "custom/tailscale-ping"
          # "custom/gamemode"
          "battery"
          "tray"
          "privacy"
          "idle_inhibitor"
        ];

        clock = {
          format = "{:%d/%m %H:%M}";
          tooltip-format = ''
            <big>{:%Y %B}</big>
            <tt><small>{calendar}</small></tt>'';
        };
        cpu = {
          format = "Óâ¶   {usage}%";
        };
        "custom/gpu" = {
          interval = 5;
          return-type = "json";
          exec = jsonOutput "gpu" {
            text = "$(${cat} /sys/class/drm/card0/device/gpu_busy_percent)";
            tooltip = "GPU Usage";
          };
          format = "Û∞íã  {}%";
        };
        memory = {
          format = "Û∞çõ  {}%";
          interval = 5;
        };
        pulseaudio = {
          format = "{icon}  {volume}%";
          format-muted = "Ôë¶   0%";
          format-icons = {
            headphone = "Û∞ãã";
            headset = "Û∞ãé";
            portable = "ÔÇï";
            default = ["ÔÄ¶" "ÔÄß" "ÔÄ®"];
          };
          on-click = pavucontrol;
        };
        idle_inhibitor = {
          format = "{icon}";
          format-icons = {
            activated = "Û∞í≥";
            deactivated = "Û∞í≤";
          };
        };
        battery = {
          bat = "BAT0";
          interval = 10;
          format-icons = ["Û∞Å∫" "Û∞Åª" "Û∞Åº" "Û∞ÅΩ" "Û∞Åæ" "Û∞Åø" "Û∞ÇÄ" "Û∞ÇÅ" "Û∞ÇÇ" "Û∞Åπ"];
          format = "{icon} {capacity}%";
          format-charging = "Û∞ÇÑ {capacity}%";
          onclick = "";
        };
        "sway/window" = {
          max-length = 20;
        };
        network = {
          interval = 3;
          format-wifi = "Ôá´   {essid}";
          format-ethernet = "Û∞àÅ Connected";
          format-disconnected = "";
          tooltip-format = ''
            {ifname}
            {ipaddr}/{cidr}
            Up: {bandwidthUpBits}
            Down: {bandwidthDownBits}'';
          on-click = "";
        };
        "custom/tailscale-ping" = {
          interval = 10;
          return-type = "json";
          exec = let
            inherit (builtins) concatStringsSep attrNames;
            hosts = attrNames outputs.nixosConfigurations;
            homeMachine = "hestia";
            remoteMachine = "horus";
          in
            jsonOutput "tailscale-ping" {
              # Build variables for each host
              pre = ''
                set -o pipefail
                ${concatStringsSep "\n" (map (host: ''
                    ping_${host}="$(${timeout} 2 ${ping} -c 1 -q ${host} 2>/dev/null | ${tail} -1 | ${cut} -d '/' -f5 | ${cut} -d '.' -f1)ms" || ping_${host}="Disconnected"
                  '')
                  hosts)}
              '';
              # Access a remote machine's and a home machine's ping
              text = "ÓàÆ  $ping_${remoteMachine} / ÔÄï $ping_${homeMachine}";
              # Show pings from all machines
              tooltip = concatStringsSep "\n" (map (host: "${host}: $ping_${host}") hosts);
            };
          format = "{}";
          on-click = "";
        };
        "custom/unread-mail" = {
          interval = 5;
          return-type = "json";
          exec = jsonOutput "unread-mail" {
            pre = ''
              count=$(${find} ~/Mail/*/Inbox/new -type f | ${wc} -l)
              if [ "$count" == "0" ]; then
                subjects="No new mail"
                status="read"
              else
                subjects=$(\
                  ${grep} -h "Subject: " -r ~/Mail/*/Inbox/new | ${cut} -d ':' -f2- | \
                  ${perl} -CS -MEncode -ne 'print decode("MIME-Header", $_)' | ${xml} esc | ${sed} -e 's/^/\-/'\
                )
                status="unread"
              fi
              if ${pgrep} mbsync &>/dev/null; then
                status="syncing"
              fi
            '';
            text = "$count";
            tooltip = "$subjects";
            alt = "$status";
          };
          format = "{icon}  ({})";
          format-icons = {
            "read" = "Û∞áØ";
            "unread" = "Û∞áÆ";
            "syncing" = "Û∞Å™";
          };
        };
        /*
        TODO
            "custom/gpg-agent" = {
              interval = 2;
              return-type = "json";
              exec =
                let gpgCmds = import ../../../cli/gpg-commands.nix { inherit pkgs; };
                in
                jsonOutput "gpg-agent" {
                  pre = ''status=$(${gpgCmds.isUnlocked} && echo "unlocked" || echo "locked")'';
                  alt = "$status";
                  tooltip = "GPG is $status";
                };
              format = "{icon}";
              format-icons = {
                "locked" = "ÔÄ£";
                "unlocked" = "ÔÇú";
              };
              on-click = "";
            };
        */
        "custom/gamemode" = {
          exec-if = "${gamemoded} --status | ${grep} 'is active' -q";
          interval = 2;
          return-type = "json";
          exec = jsonOutput "gamemode" {
            tooltip = "Gamemode is active";
          };
          format = "ÔÑõ ";
        };
        "custom/gammastep" = {
          interval = 5;
          return-type = "json";
          exec = jsonOutput "gammastep" {
            pre = ''
              if unit_status="$(${systemctl} --user is-active gammastep)"; then
                status="$unit_status ($(${journalctl} --user -u gammastep.service -g 'Period: ' | ${tail} -1 | ${cut} -d ':' -f6 | ${xargs}))"
              else
                status="$unit_status"
              fi
            '';
            alt = "\${status:-inactive}";
            tooltip = "Gammastep is $status";
          };
          format = "{icon}";
          format-icons = {
            "activating" = "Û∞Å™ ";
            "deactivating" = "Û∞Å™ ";
            "inactive" = "? ";
            "active (Night)" = "ÔÜÜ ";
            "active (Nighttime)" = "ÔÜÜ ";
            "active (Transition (Night)" = "ÔÜÜ ";
            "active (Transition (Nighttime)" = "ÔÜÜ ";
            "active (Day)" = "Óåç ";
            "active (Daytime)" = "Óåç ";
            "active (Transition (Day)" = "Óåç ";
            "active (Transition (Daytime)" = "Óåç ";
          };
          on-click = "${systemctl} --user is-active gammastep && ${systemctl} --user stop gammastep || ${systemctl} --user start gammastep";
        };
        "custom/currentplayer" = {
          interval = 2;
          return-type = "json";
          exec = jsonOutput "currentplayer" {
            pre = ''
              player="$(${playerctl} status -f "{{playerName}}" 2>/dev/null || echo "No player active" | ${cut} -d '.' -f1)"
              count="$(${playerctl} -l 2>/dev/null | ${wc} -l)"
              if ((count > 1)); then
                more=" +$((count - 1))"
              else
                more=""
              fi
            '';
            alt = "$player";
            tooltip = "$player ($count available)";
            text = "$more";
          };
          format = "{icon}{}";
          format-icons = {
            "No player active" = "ÔÄÅ ";
            "Celluloid" = "Û∞éÅ ";
            "spotify" = " Û∞ìá";
            "ncspot" = " Û∞ìá";
            "qutebrowser" = "Û∞ñü";
            "firefox" = "Ôâ© ";
            "discord" = " Û∞ôØ ";
            "sublimemusic" = "ÔÉÇ ";
            "kdeconnect" = "Û∞Ñ° ";
          };
          on-click = "${playerctld} shift";
          on-click-right = "${playerctld} unshift";
        };
        "custom/player" = {
          exec-if = "${playerctl} status 2>/dev/null";
          exec = ''${playerctl} metadata --format '{"text": "{{title}} - {{artist}}", "alt": "{{status}}", "tooltip": "{{title}} - {{artist}} ({{album}})"}' 2>/dev/null '';
          return-type = "json";
          interval = 2;
          max-length = 30;
          format = "{icon} {}";
          format-icons = {
            "Playing" = "Û∞êä";
            "Paused" = "Û∞è§ ";
            "Stopped" = "Û∞ìõ";
          };
          on-click = "${playerctl} play-pause";
        };
        "custom/events" = {
          tooltip = true;
          interval = 60;
          format = "{icon} {}";
          format-icons.default = "ÔÅ≥";
          exec = let
            script =
              pkgs.writeText "script.py"
              ''
                import json
                import subprocess
                data = {}
                output = subprocess.check_output("${khal} list now 7days --format \"{start-end-time-style} {title}\"", shell=True).decode("utf-8")
                lines = output.split("\n")
                new_lines = []
                for line in lines:
                    if len(line) and line[0].isalpha():
                        line = "\n<b>"+line+"</b>"
                    new_lines.append(line)
                output = "\n".join(new_lines).strip()
                if "Today" in output:
                    data['text'] = output.split('\n')[1]
                else:
                    data['text'] = "No event today"
                data['tooltip'] = output
                print(json.dumps(data))
              '';
          in "${python} ${script}";
          return-type = "json";
        };
        "hyprland/workspaces" = {
          format-window-separator = "";
          active-only = false;
          all-outputs = false;
          show-special = true;
          window-rewrite-default = "";
          format = "{name}{windows}";
          "window-rewrite" = {
            "title<.*youtube.*>" = " ÔÖ™";
            "class<firefox>" = " Ôâ©";
            "class<firefox> title<.*github.*>" = " ÔÑì";
            "warp" = " Óûï";
            "kitty" = " Óûï";
            "codium-url-handler" = " Û∞®û";
            "Discord" = " Û∞ôØ";
            "class<Spotify>" = " Û∞ìá";
            "matlab" = "Û∞Üß";
            "Super Productivity" = " Û∞®ü";
            "Beeper" = " üí¨";
            "LM Studio" = " ÔÑ´";
            "KeepassXC" = " ÔÄ£";
          };
        };
      };
    };
  };
}
