{ lib, config, pkgs, ... }:
let
  swayosd-client = lib.getExe' config.services.swayosd.package "swayosd-client";
in {
  config = {
    programs.waybar = {
      enable = false; # true;
      systemd = {
        enable = true;
        target = "graphical-session.target";
      };
      settings = let
        windowRewrites = {
          "(.*) — Mozilla Firefox" = "$1";
          "(.*) - Mozilla Thunderbird" = "$1";
          "(.*) - mpv" = "$1";
        };
        iconSize = 11;
      in [
        {
          layer = "top";
          position = "top";
          height = 21;
          output = [ "eDP-1" "DP-2" "DP-3" ];
          modules-left = [ "niri/workspaces" ];
          modules-center = [ "niri/window" ];
          modules-right = [ "custom/worktime" "custom/worktime-today"
            "custom/weather"
            "custom/keymap"
            "privacy" "tray" "wireplumber" "backlight" "battery" "idle_inhibitor" "custom/mako" "custom/lid_inhibitor" "clock" ];
          "custom/lid_inhibitor" = {
            format = "{}";
            return-type = "json";
            exec = lib.getExe pkgs.waybar-systemd-inhibit;
            on-click = lib.getExe' pkgs.waybar-systemd-inhibit "waybar-systemd-inhibit-toggle";
          };
          "custom/mako" = {
            format = "{}";
            return-type = "json";
            exec = pkgs.writers.writePython3 "mako-silent" { libraries = [ pkgs.python3Packages.dbus-next ]; } ''
              from dbus_next.aio import MessageBus
              import asyncio
              import json
              loop = asyncio.new_event_loop()
              asyncio.set_event_loop(loop)
              async def main():
                  bus = await MessageBus().connect()
                  # the introspection xml would normally be included in your project, but
                  # this is convenient for development
                  introspection = await bus.introspect('org.freedesktop.Notifications', '/fr/emersion/Mako')  # noqa: E501
                  obj = bus.get_proxy_object('org.freedesktop.Notifications', '/fr/emersion/Mako', introspection)  # noqa: E501
                  mako = obj.get_interface('fr.emersion.Mako')
                  properties = obj.get_interface('org.freedesktop.DBus.Properties')
                  async def print_mode():
                      modes = await mako.get_modes()
                      is_silent = "silent" in modes
                      icon = "" if is_silent else ""
                      text = f"{icon}"  # noqa: E501
                      if is_silent:
                          text = f"{text}"
                      print(json.dumps({'text': text, 'tooltip': ', '.join(modes)}, separators=(',', ':')), flush=True)  # noqa: E501
                  async def on_properties_changed(interface_name, changed_properties, invalidated_properties):  # noqa: E501
                      if "Modes" not in invalidated_properties:
                          return
                      await print_mode()
                  properties.on_properties_changed(on_properties_changed)
                  await print_mode()
                  await loop.create_future()
              loop.run_until_complete(main())
            '';
            on-click = "makoctl mode -t silent";
          };
          "custom/weather" = {
            format = "{}";
            tooltip = true;
            interval = 3600;
            exec = "${lib.getExe pkgs.wttrbar} --hide-conditions --nerd --custom-indicator \"{ICON} {FeelsLikeC}°\"";
            return-type = "json";
          };
          "custom/keymap" = {
            format = "{}";
            tooltip = true;
            return-type = "json";
            exec = pkgs.writers.writePython3 "keymap" {} ''
              import os
              import socket
              import json
              def output(keymap):
                  short = keymap
                  if keymap == "English (programmer Dvorak)":
                      short = "dvp"
                  elif keymap == "English (US)":
                      short = "us"
                  print(json.dumps({'text': short, 'tooltip': keymap}, separators=(',', ':')), flush=True)  # noqa: E501
              keyboard_layouts = []
              sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
              sock.connect(os.environ["NIRI_SOCKET"])
              sock.send(b"\"EventStream\"\n")
              for line in sock.makefile(buffering=1, encoding='utf-8'):
                  if line_json := json.loads(line):
                      if "KeyboardLayoutsChanged" in line_json:
                          keyboard_layouts = line_json["KeyboardLayoutsChanged"]["keyboard_layouts"]["names"]  # noqa: E501
                          output(keyboard_layouts[line_json["KeyboardLayoutsChanged"]["keyboard_layouts"]["current_idx"]])  # noqa: E501
                      if "KeyboardLayoutSwitched" in line_json:
                          output(keyboard_layouts[line_json["KeyboardLayoutSwitched"]["idx"]])  # noqa: E501
            '';
            on-click = "niri msg action switch-layout next";
          };
          "custom/worktime" = {
            interval = 60;
            exec = "${lib.getExe pkgs.worktime} time --waybar";
            return-type = "json";
          };
          "custom/worktime-today" = {
            interval = 60;
            exec = "${lib.getExe pkgs.worktime} today --waybar";
            return-type = "json";
          };
          "niri/workspaces" = {
            ignore = map ({ name, ... }: name) config.programs.niri.scratchspaces;
          };
          "niri/window" = {
            separate-outputs = true;
            icon = true;
            icon-size = 14;
            rewrite = windowRewrites;
          };
          clock = {
              interval = 1;
              # timezone = "Europe/Berlin";
              format = "W{:%V-%u %F %H:%M:%S%Ez}";
              tooltip-format = "{calendar}";
              calendar = {
                mode = "year";
                mode-mon-col = 3;
                weeks-pos = "left";
                on-scroll = 1;
                format = {
                  months = "{}";
                  days = "{}";
                  weeks = "{}";
                  weekdays = "{}";
                  today = "{}";
                };
              };
          };
          battery = {
            format = "{icon}";
            icon-size = iconSize - 2;
            states = { warning = 30; critical = 15; };
            format-icons = ["" "" "" "" "" "" "" "" "" "" "" ];
            format-charging = "";
            format-plugged = "";
            tooltip-format = "{capacity}% {timeTo}";
            interval = 20;
          };
          tray = {
            icon-size = 16;
            # show-passive-items = true;
            spacing = 1;
          };
          privacy = {
            icon-spacing = 7;
            icon-size = iconSize;
            modules = [
              { type = "screenshare"; }
              { type = "audio-in"; }
            ];
          };
          idle_inhibitor = {
            format = "{icon}";
            icon-size = iconSize;
            format-icons = { activated = ""; deactivated = ""; };
            timeout = 120;
          };
          backlight = {
            format = "{icon}";
            icon-size = iconSize;
            tooltip-format = "{percent}%";
            format-icons = ["" "" "" "" "" "" ""];
            on-scroll-up = "${swayosd-client} --brightness raise";
            on-scroll-down = "${swayosd-client} --brightness lower";
          };
          wireplumber = {
            format = "{icon}";
            icon-size = iconSize;
            tooltip-format = "{volume}% {node_name}";
            format-icons = ["" "" ""];
            format-muted = "";
            # ignored-sinks = ["Easy Effects Sink"];
            on-scroll-up = "${swayosd-client} --output-volume raise";
            on-scroll-down = "${swayosd-client} --output-volume lower";
            on-click = "${swayosd-client} --output-volume mute-toggle";
          };
        }
        {
          layer = "top";
          position = "top";
          height = 14;
          output = [ "!eDP-1" "!DP-2" "!DP-3" "*" ];
          modules-left = [ "niri/workspaces" ];
          modules-center = [ "niri/window" ];
          modules-right = [ "clock" ];
          "niri/workspaces" = {
            ignore = map ({ name, ... }: name) config.programs.niri.scratchspaces;
          };
          "niri/window" = {
            separate-outputs = true;
            icon = true;
            icon-size = 14;
            rewrite = windowRewrites;
          };
          clock = {
              interval = 1;
              # timezone = "Europe/Berlin";
              format = "{:%H:%M}";
              tooltip-format = "W{:%V-%u %F %H:%M:%S%Ez}";
          };
        }
      ];
      style = ''
        @define-color white #ffffff;
        @define-color grey #555555;
        @define-color blue #1a8fff;
        @define-color green #23fd00;
        @define-color orange #f28a21;
        @define-color red #f2201f;
        * {
          border: none;
          font-family: "Fira Sans";
          font-size: 10pt;
          min-height: 0;
        }
        window#waybar {
          background-color: rgba(0, 0, 0, 0.66);
          color: @white;
        }
        .modules-left {
          margin-left: 38px;
        }
        .modules-right {
          margin-right: 38px;
        }
        .module {
          margin: 0 5px;
        }
        #workspaces button {
          color: @white;
          padding: 2px 5px;
        }
        #workspaces button.empty {
          color: @grey;
        }
        #workspaces button.active {
          color: @green;
        }
        #workspaces button.urgent {
          color: @red;
        }
        #custom-weather, #custom-keymap, #custom-worktime, #custom-worktime-today {
          color: @grey;
          margin: 0 5px;
        }
        #custom-weather {
          margin-right: 3px;
        }
        #custom-keymap {
          margin-left: 3px;
          margin-right: 3px;
        }
        #tray {
          margin: 0;
        }
        #battery, #idle_inhibitor, #backlight, #wireplumber, #custom-mako, #custom-lid_inhibitor {
          color: @grey;
          margin: 0 5px 0 2px;
        }
        #idle_inhibitor {
          margin-right: 4px;
          margin-left: 6px;
        }
        #custom-mako {
          margin-right: 4px;
          margin-left: 3px;
        }
        #custom-lid_inhibitor {
          margin-right: 3px;
          margin-left: 3px;
        }
        #battery {
          margin-right: 3px;
        }
        #battery.discharging {
          color: @white;
        }
        #battery.warning {
          color: @orange;
        }
        #battery.critical {
          color: @red;
        }
        #battery.charging {
          color: @white;
        }
        #idle_inhibitor.activated {
          color: @white;
        }
        #custom-worktime.running, #custom-worktime-today.running {
          color: @white;
        }
        #custom-worktime.over, #custom-worktime-today.over {
          color: @orange;
        }
        #idle_inhibitor, #custom-lid_inhibitor {
          padding-top: 1px;
        }
        #privacy {
          color: @red;
          margin: -1px 4px 0px 3px;
        }
        #clock {
          /* margin-right: 5px; */
          font-feature-settings: "tnum";
        }
      '';
    };
  };
}