#
# Use Waybar with our GUI.
#
# vim: et:ts=2:sw=2:
{
  lib,
  pkgs,
  config,
  ...
}:
let
  hostname = config.networking.hostName;
  isAmd = config.hardware.cpu.amd.updateMicrocode;
  isSmallScreen = (hostname == "utol");
  cfg = config.deprekated.waybar;
in
{
  options.deprekated.waybar = {

    hostSpecificCss = lib.mkOption {
      type = lib.types.str;
      default = "";
      example = ''
        window#waybar {
            padding-left: 8px;
            padding-right: 8px;
        }
      '';
      description = ''
        CSS to add to our waybar config on this system.
      '';
    };
  };

  config = {

    # Pull in some dependencies for our bar.
    environment.systemPackages = with pkgs; [ networkmanagerapplet ];

    # Enable the yubikey touch detector, for our icon.
    programs.yubikey-touch-detector.enable = true;

    #
    # Set up our waybar configuration in home-manager.
    #
    home-manager.users.deprekated =
      { pkgs, config, ... }:
      let

        icons = rec {
          calendar = "󰃭 ";
          clock = " ";
          puclock = "󱑆";
          cpu = "";
          ram = "";
          battery.charging = "󱐋";
          battery.horizontal = [
            " "
            " "
            " "
            " "
            " "
          ];
          battery.vertical = [
            "󰁺"
            "󰁻"
            "󰁼"
            "󰁽"
            "󰁾"
            "󰁿"
            "󰂀"
            "󰂁"
            "󰂂"
            "󰁹"
          ];
          battery.levels = battery.vertical;
          network.disconnected = "󰤮 ";
          network.ethernet = "󰈀 ";
          network.strength = [
            "󰤟 "
            "󰤢 "
            "󰤥 "
            "󰤨 "
          ];
          bluetooth.on = "󰂯";
          bluetooth.off = "󰂲";
          bluetooth.battery = "󰥉";
          volume.source = "󱄠";
          volume.muted = "󰝟";
          volume.levels = [
            "󰕿"
            "󰖀"
            "󰕾"
          ];
          idle = {
            on = "<span color='#${colors.red}'>󰅶</span>";
            off = "󰾪";
          };
          vpn = "󰌆 ";
          music = {
            playing = "";
            paused = "";
            stopped = "";
            missing = "󰌙";
          };

          speed = {
            slow = "󰾆";
            medium = "󰾅";
            fast = "󰓅";
          };
        };
        colors = config.lib.stylix.colors;

        # From the Waybar wiki.
        waybar-events = pkgs.writeScriptBin "waybar-events" ''
          #!${pkgs.python3}/bin/python3

          import calendar
          import subprocess
          import datetime
          import json
          import html
          import sys

          data = {}

          today = datetime.date.today().strftime("%Y-%m-%d")
          next_week = (datetime.date.today() +
                      datetime.timedelta(days=10)).strftime("%Y-%m-%d")
          tomorrow = (datetime.date.today() +
                      datetime.timedelta(days=1)).strftime("%Y-%m-%d")

          human_events = subprocess.check_output('khal list now ' + next_week, shell=True).decode('utf-8')
          machine_events = subprocess.check_output('khal list now ' + next_week + ' -d "Holidays in United States" --once -f "{title}|{start-date}|{start-time}" -df ""', shell=True).decode('utf-8')

          if not machine_events:
              sys.exit(0)

          next_event = machine_events.split("\n")[0]
          event, date, time = next_event.split('|')

          # Generate our hover-over text.
          lines = human_events.split("\n")
          new_lines = []
          for line in lines:
              if line.startswith("To hide observances") or (line == ""):
                  continue

              clean_line = html.escape(line).split(" ::")[0]
              if len(clean_line) and not clean_line[0] in ['0', '1', '2']:
                  clean_line = "\n<b><span color='#${colors.blue}'>"+clean_line+"</span></b>" if (',' in clean_line) else clean_line

              new_lines.append(clean_line)
          tooltip = "\n".join(new_lines).strip()

          if tomorrow in date:
            date = "tomorrow"
          else:
            weekday = datetime.datetime.fromisoformat(date).weekday()
            date = calendar.day_name[weekday].lower()


          # Add time suffixes when appropriate.
          time_suffix = ""
          if time:
            time_suffix = " @ " + time

          date_suffix = ""
          if today not in date:
            date_suffix = ", " + date


          # In the typical case, display the next event.
            data['text'] = html.escape(" " + event[0:30] + date_suffix + time_suffix)

          # Display our nice, human-readable event ouptut on hover.
          data['tooltip'] = tooltip

          # Finally, send the data to Waybar.
          print(json.dumps(data))
        '';

        waybar-title = pkgs.writeScriptBin "waybar-title" ''
          #!${pkgs.bash}/bin/bash
          niri msg --json focused-window | jq -c '{text: (if ((.title | length) > 40) then (.title[:38] + "…") else .title end), tooltip: .app_id}' | sed 's/&[ $]/\&amp; /g'
        '';
      in
      {
        #
        # Core Waybar settings.
        #
        programs.waybar = {
          enable = true;
          #systemd.enable = true;
        };

        programs.waybar.settings.mainBar =
          {
            layer = "top";
            #mode = "overlay";

            modules-left = [
              "clock"
              "mpris"
            ];
            modules-center = [
              "custom/title"
              "wlr/taskbar"
            ];
            modules-right = [
              "tray"
              "custom/events"
              "privacy"
              "custom/yubikey"
              "wireplumber"
              "battery"
            ] ++ (if isAmd then [ "power-profiles-daemon" ] else [ ]);

            battery = {
              interval = 5;
              format = "{icon} {capacity}%";
              format-charging = "{icon} {capacity}% ${icons.battery.charging}";
              format-icons = icons.battery.levels;
              states.warning = 30;
              states.critical = 15;
            };

            cpu = {
              format = "${icons.cpu} {usage}% @ {avg_frequency:0.1f}GHz";
            };

            memory = {
              format = "${icons.ram}  {used:0.1f}G / {total:0.1f}G";
            };

            clock = {
              interval = 1;
              format = "${icons.clock} {:%H:%M %A, %B %d %Z}";

              tooltip-format = "<tt>${icons.calendar}<u><b> {:%a, %Y-%m-%d}</b></u>\n\n{calendar}</tt>";

              calendar = {
                mode = "month";
                format = {
                  weeks = "<b>W{}</b>";
                  months = "<span color='#${colors.magenta}'><b>{}</b></span>";
                  days = "<span color='#${colors.blue}'><b>{}</b></span>";
                  weekdays = "<span color='#${colors.cyan}'><b>{}</b></span>";
                  today = "<span color='#${colors.green}'><b>{}</b></span>";
                };
              };
            };

            network = {
              on-click = "${pkgs.networkmanagerapplet}/bin/nm-connection-editor";
              tooltip = false;
              format-disconnected = icons.network.disconnected;
              format-ethernet = "${icons.network.ethernet}";
              format-wifi = "{icon} {essid}";
              format-icons = icons.network.strength;
            };

            bluetooth = {
              format = "{icon}";
              format-disabled = "{icon}";
              format-icons = {
                inherit (icons.bluetooth) on off;
                connected = icons.bluetooth.on;
              };
              format-connected = "{icon} {device_alias}";
            };
            "bluetooth#battery" = {
              format = "";
              format-connected-battery = "${icons.bluetooth.battery} {device_battery_percentage}%";
            };

            wireplumber = {
              on-click = "${pkgs.pavucontrol}/bin/pavucontrol -t 1";
              format = "{icon} {volume}%";
              tooltip-format = "${icons.volume.source}";
              format-muted = "${icons.volume.muted}";
              format-icons = icons.volume.levels;
              reverse-scrolling = 1;
            };

            # Displays an icon when our yubikey is waiting for touch.
            "custom/yubikey" = {
              exec = ./waybar-yubikey.sh;
              return-type = "json";
            };

            "custom/events" = {
              exec = "${waybar-events}/bin/waybar-events";
              format = "{}";
              tooltip = true;
              return-type = "json";
              interval = 60;
              on-click = "${pkgs.wezterm}/bin/wezterm start ikhal";
            };

            "custom/title" = {
              exec = "${waybar-title}/bin/waybar-title";
              format = "{}";
              tooltip = true;
              return-type = "json";
              interval = 1;
            };

            "wlr/taskbar" = {
              format = "{icon}";
              tooltip-format = "{app_id}";

              on-click = "activate";
            };

            tray = {
              icon-size = 21;
              spacing = 10;
            };

            # Display indicators when we're sharing video or audio.
            privacy = {
              icon-spacing = 4;
              icon-size = 18;
              transition-duration = 250;
              modules = [
                {
                  type = "screenshare";
                  tooltip = false;
                  tooltip-icon-size = 24;
                }
                {
                  type = "audio-out";
                  tooltip = false;
                  tooltip-icon-size = 24;
                }
                {
                  type = "audio-in";
                  tooltip = false;
                  tooltip-icon-size = 24;
                }
              ];
            };

            mpris = {
              format = "${icons.music.playing} {artist} - {title}";
              format-paused = "${icons.music.paused} {artist} - {title}";
              format-stopped = "";
              format-disconnected = "${icons.music.missing}";
              tooltip-format = "${icons.music.playing} {artist} - {title}";
              max-length = 60;
            };

            idle_inhibitor = {
              format = "{icon}";
              format-icons = {
                activated = icons.idle.on;
                deactivated = icons.idle.off;
              };

              tooltip-format-activated = "System <span color='#${colors.orange}'><b>blocked</b></span> from going idle.";
              tooltip-format-deactivated = "System <span color='#${colors.green}'><b>allowed</b></span> to go idle.";
            };
          }
          // (
            # Support PPD on AMD.
            if isAmd then
              {
                power-profiles-daemon = {
                  format = "{icon} ";
                  tooltip-format = "Power profile: {profile}nDriver: {driver}";
                  tooltip = true;
                  format-icons = {
                    default = "";
                    performance = "";
                    balanced = "";
                    power-saver = "";
                  };
                };
              }
            else
              { }
          );
        stylix.targets.waybar.enable = false;
        programs.waybar.style =
          let
            colors = config.lib.stylix.colors;
            modules = s: "${s ".modules-left"}, ${s ".modules-center"}, ${s ".modules-right"}";
            module = s: modules (m: "${m} > ${s} > *");
          in
          ''
            * {
                border: none;
                font-family: ${config.stylix.fonts.monospace.name};
                font-weight: 400;
                font-size: ${if isSmallScreen then "17" else toString config.stylix.fonts.sizes.desktop}px;
                color: #${colors.base06};
            }

            ${cfg.hostSpecificCss}

            window#waybar {
                background: #${colors.base00};
            }

            #taskbar button {
              padding: 0 0.4em;
            }

            #taskbar button.active {
              background: #${colors.base01};
            }

            #tray image,
            #taskbar image {
              -gtk-icon-transform: scale(0.75);
              margin: -5px -4px;
              padding: 0px 2px;
            }

            ${modules lib.id} {
                margin: 0;
            }

            ${module "*"} {
              padding: 0 5px;
              margin: 0;
              font-size: 75%;
            }

            ${module ":not(:first-child)"} {
              border-left: 1px solid #${colors.base01};
            }

            ${module ":not(:last-child)"} {
              border-right: 1px solid #${colors.base01};
            }

            #battery.charging {
                color: #${colors.green};
            }

            #battery.warning:not(.charging) {
                color: #${colors.yellow};
            }

            #battery.critical:not(.charging) {
                animation: critical-blink steps(8) 1s infinite alternate;
            }

            @keyframes critical-blink {
                to {
                    color: #${colors.red};
                }
            }
          '';

        #
        # Restart waybar when niri starts.
        #
        programs.niri.settings.spawn-at-startup = [
          {
            command = [
              "systemctl"
              "--user"
              "restart"
              "waybar"
            ];
          }
          { command = [ "nm-applet" ]; }
        ];
      };
  };
}
