{ config, lib, ... }:
with lib;
let
  cfg = config.mjallen.programs.waybar;
  palette = import cfg.theme.file;

  defaultOpacity = palette.tokens.opacity or "opacity: 0.85;";
  defaultBorderRadius = palette.tokens.borderRadius or "border-radius: 1rem;";
  defaultCenterOptions =
    palette.tokens.centerOptions or ''
      padding-top: 0.2rem;
      padding-bottom: 0.2rem;
      padding-left: 0.5rem;
      padding-right: 0.5rem;
      margin: 3px 0;
    '';
  borderRight =
    palette.tokens.borderRight or ''
      padding-top: 0.2rem;
      padding-bottom: 0.2rem;
      padding-left: 0.5rem;
      padding-right: 0.5rem;
      margin: 3px 0;
      border-radius: 0rem 1rem 1rem 0rem;
      margin-right: 0.5rem;
    '';
  borderLeft = ''
    padding-top: 0.2rem;
    padding-bottom: 0.2rem;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
    margin: 3px 0;
    border-radius: 1rem 0rem 0rem 1rem;
    margin-left: 0.5rem;
  '';

  baseStyle =
    if cfg.style.file != null then
      builtins.readFile cfg.style.file
    else
      ''
        .blink_me {
          animation: blinker 1s linear infinite;
        }

        @keyframes blinker {
          50% {
            color: ${palette.colors.danger};
          }
        }

        * {
          font-family:
            Jetbrains Mono Nerd Font,
            monospace;
          font-size: 14px;
          min-height: 0;
        }

        #waybar {
          background: transparent;
          color: ${palette.colors.text};
          margin: 5px 5px;
        }

        #workspaces {
          background-color: ${palette.colors.bg};
          ${defaultBorderRadius}
          ${defaultOpacity}
          ${defaultCenterOptions}
          margin-left: 0.6rem;
        }

        #workspaces button {
          color: ${palette.colors.primary};
          ${defaultBorderRadius}
          padding: 0.4rem;
        }

        #workspaces button.active {
          color: ${palette.colors.info};
          ${defaultBorderRadius}
        }

        #workspaces button:hover {
          color: ${palette.colors.info};
          ${defaultBorderRadius}
        }

        #workspaces button.focused {
          color: ${palette.colors.text};
          background: ${palette.colors.warning};
          ${defaultBorderRadius}
        }

        #workspaces button.urgent {
          color: ${palette.colors.bg};
          background: ${palette.colors.text};
          ${defaultBorderRadius}
        }

        #tooltip {
          background: ${palette.colors.bg};
          border-color: ${palette.colors.bg};
          ${defaultBorderRadius}
          border-width: 1rem;
          border-style: solid;
        }

        #window {
          color: ${palette.colors.accent};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultBorderRadius}
          ${defaultCenterOptions}
          margin-left: 4rem;
          margin-right: ${toString cfg.windowOffset}rem;
        }

        /* make window module transparent when no windows present */
        #window.empty {
          background-color: transparent;
        }

        #custom-weather { 
          color: ${palette.colors.primary};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
        }

        #battery {
          color: ${palette.colors.accent};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
          min-width: 3rem;
        }

        #clock {
          color: ${palette.colors.primary};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
        }

        /* ------------- */

        #idle_inhibitor {
          color: ${palette.colors.primary};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
          padding-right: 1rem;
        }

        #idle_inhibitor:hover {
          background: ${palette.colors.surfaceAlt};
        }

        #network {
          color: ${palette.colors.accent};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
          padding-right: 15px;
        }

        #network:hover {
          background: ${palette.colors.surfaceAlt};
        }

        #bluetooth {
          color: ${palette.colors.primary};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
        }

        #bluetooth:hover {
          background: ${palette.colors.surfaceAlt};
        }

        #wireplumber.source {
          color: ${palette.colors.info};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
        }

        #wireplumber.source.muted {
          animation-name: blinker;
          animation-duration: 2s;
          animation-timing-function: linear;
          animation-iteration-count: infinite;
          padding-right: 1rem;
        }

        #wireplumber.source:hover {
          background: ${palette.colors.surfaceAlt};
        }

        #wireplumber.sink {
          color: ${palette.colors.info};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
        }

        #wireplumber.sink.muted {
          animation-name: blinker;
          animation-duration: 5s;
          animation-timing-function: linear;
          animation-iteration-count: infinite;
        }

        #wireplumber.sink:hover {
          background: ${palette.colors.surfaceAlt};
        }

        #keyboard-state.numlock {
          color: ${palette.colors.info};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
        }

        #keyboard-state.capslock {
          color: ${palette.colors.primary};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
        }

        #temperature.gpu {
          color: ${palette.colors.primary};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0;
        }

        #temperature.gpu:hover {
          background: ${palette.colors.surfaceAlt};
        }

        #temperature {
          color: ${palette.colors.primary};
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          border-radius: 0
        }

        /* ------------- */

        #tray {
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${defaultCenterOptions}
          ${defaultBorderRadius}
          margin-right: 0.6rem;
        }

        /* ------------- */

        #custom-left-end {
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${borderLeft}
        }

        #custom-right-end {
          background-color: ${palette.colors.bg};
          ${defaultOpacity}
          ${borderRight}
        }
      '';
in
{
  imports = [
    ./options.nix
    ./scripts/audio-control.nix
    ./scripts/hass.nix
    ./scripts/weather.nix
  ];

  config = mkIf cfg.enable {
    # https://github.com/Alexays/Waybar/wiki/Module:-Hyprland
    # https://www.nerdfonts.com/cheat-sheet

    programs.waybar = {
      enable = true;
      systemd.enable = true;

      settings = {
        mainBar = (
          (mkMerge [
            {
              layer = cfg.layer;
              position = "top";
              mod = "dock";
              exclusive = true;
              passthrough = false;
              gtk-layer-shell = true;
              height = 0;

              # Module Layout
              modules-left = cfg.layout.left;
              modules-center = cfg.layout.center;
              modules-right = cfg.layout.right;

              # Base module definitions always present unless individually gated
              "hyprland/workspaces" = {
                disable-scroll = true;
                all-outputs = true;
                on-click = "activate";
                persistent_workspaces = {
                  "*" = 1;
                };
              };

              "hyprland/window" = {
                separate-outputs = true;
                format = { };
              };

              temperature = {
                hwmon-path-abs = cfg.temperature.cpu.hwmonPath;
                input-filename = cfg.temperature.cpu.hwmonFile;
                critical-threshold = 110;
                format-critical = "{temperatureC}°C ";
                format = "{temperatureC}°C {icon}";
                format-icons = [
                  ""
                  ""
                  ""
                  ""
                  ""
                ];
                tooltip-format = "CPU: {temperatureC}°C";
              };

              network = {
                interface = cfg.network.interface;
                on-click = "nm-connection-editor";
                format = "{icon}";
                tooltip-format = "{ifname} via {gwaddr} 󰊗";
                tooltip-format-wifi = ''
                  {essid} ({signalStrength}%) {icon}
                   {bandwidthDownBits}  {bandwidthUpBits}
                '';
                tooltip-format-ethernet = "{ifname} ";
                tooltip-format-disconnected = "Disconnected";
                max-length = 50;
                format-icons = {
                  wifi = [
                    "󰤯"
                    "󰤟"
                    "󰤢"
                    "󰤥"
                    "󰤨"
                  ];
                  ethernet = "󰈀";
                  linked = "󰤫";
                  disconnected = "󰤫";
                };
              };

              "custom/left-end" = {
                format = "&nbsp";
                tooltip = false;
              };

              "custom/right-end" = {
                format = "&nbsp";
                tooltip = false;
              };
            }

            (mkIf cfg.features.tray.enable {
              tray = {
                icon-size = 16;
                spacing = 10;
              };
            })

            (mkIf cfg.features.keyboardIndicators.enable {
              "keyboard-state#capslock" = {
                capslock = true;
                format = "{icon}";
                tooltip-format = "Caps Lock {state}";
                format-icons = {
                  locked = "󰬶";
                  unlocked = "󰬵";
                };
              };

              "keyboard-state#numlock" = {
                numlock = true;
                format = "{icon}";
                tooltip-format = "Num Lock {state}";
                format-icons = {
                  locked = "󰎠";
                  unlocked = "󱧓";
                };
              };
            })

            (mkIf cfg.features.audio.sink.enable {
              "wireplumber#sink" = {
                format = "{icon} {volume}%";
                tooltip-format = "{icon}\n{node_name}\n{format_source}\n{source_desc}";
                format-muted = "{icon} Muted";
                on-click = "wpctl set-mute @DEFAULT_SINK@ toggle";
                on-click-right = "pavucontrol -t 1";
                on-scroll-up = "wpctl set-volume @DEFAULT_SINK@ 5%+";
                on-scroll-down = "wpctl set-volume @DEFAULT_SINK@ 5%-";
                on-click-middle = "waybar-audio";
                scroll-step = 5;
                format-icons = {
                  headphone = "󰋋";
                  headphone-muted = "󰟎";
                  hands-free = "󰋋";
                  headset = "󰋋";
                  phone = "";
                  portable = "󰋋";
                  car = "";
                  default = [
                    ""
                    ""
                    ""
                    ""
                  ];
                };
              };
            })

            (mkIf cfg.features.audio.source.enable {
              "wireplumber#source" = {
                node-type = "Audio/Source";
                format = "";
                format-muted = "";
                tooltip = false;
                on-click = "wpctl set-mute @DEFAULT_SOURCE@ toggle";
                on-click-right = "pavucontrol -t 2";
                on-scroll-up = "wpctl set-volume @DEFAULT_SOURCE@ 5%+";
                on-scroll-down = "wpctl set-volume @DEFAULT_SOURCE@ 5%-";
                scroll-step = 5;
              };
            })

            (mkIf cfg.features.bluetooth.enable {
              bluetooth = {
                on-click = "overskride";
                tooltip = true;
                format = "{icon}";
                tooltip-format = "{status}";
                tooltip-format-disabled = "{status}";
                tooltip-format-off = "{status}";
                tooltip-format-on = "{status}";
                tooltip-format-connected = "{status}";
                tooltip-format-enumerate-connected = { };
                format-icons = {
                  disabled = "󰂲";
                  off = "󰂲";
                  on = "󰂯";
                  connected = "󰂱";
                };
              };
            })

            (mkIf cfg.features.idleInhibitor.enable {
              idle_inhibitor = {
                format = "{icon}";
                format-icons = {
                  activated = "󰐂";
                  deactivated = "󱩜";
                };
              };
            })

            (mkIf cfg.features.clock.enable {
              clock = {
                format = "{:%I:%M %p}";
                tooltip-format = "<tt><small>{calendar}</small></tt>";
                calendar = {
                  mode = "month";
                  format = {
                    months = "<span color='${palette.colors.primary}'><b>{}</b></span>";
                    days = "<span color='${palette.colors.primary}'><b>{}</b></span>";
                    weekdays = "<span color='${palette.colors.info}'><b>{}</b></span>";
                    today = "<span color='${palette.colors.success}'><b><u>{}</u></b></span>";
                  };
                };
              };
            })

            (mkIf cfg.features.battery.enable {
              battery = {
                interval = 60;
                states = {
                  warning = 30;
                  critical = 15;
                };
                format = "{capacity}% {icon}";
                format-icons = {
                  default = [
                    "󰂃"
                    "󰁺"
                    "󰁻"
                    "󰁼"
                    "󰁽"
                    "󰁾"
                    "󰁿"
                    "󰂀"
                    "󰂁"
                    "󰂂"
                    "󰁹"
                  ];
                  charging = [
                    "󰢟"
                    "󰢜"
                    "󰂆"
                    "󰂇"
                    "󰂈"
                    "󰢝"
                    "󰂉"
                    "󰢞"
                    "󰂊"
                    "󰂋"
                    "󰂅"
                  ];
                };
                max-length = 25;
              };
            })

            (mkIf cfg.temperature.gpu.enable {
              "temperature#gpu" = {
                hwmon-path-abs = cfg.temperature.gpu.hwmonPath;
                input-filename = cfg.temperature.gpu.hwmonFile;
                critical-threshold = 110;
                format-critical = "{temperatureC}°C ";
                format = "{temperatureC}°C {icon}";
                format-icons = [
                  ""
                  ""
                  ""
                  ""
                  ""
                ];
                on-click = "lact";
                tooltip-format = "GPU: {temperatureC}°C";
              };
            })

            (mkIf cfg.features.weather.enable {
              "custom/weather" = {
                tooltip = true;
                format = { };
                interval = 30;
                exec = "waybar-weather";
                return-type = "json";
                markup = "pango";
              };
            })
          ])
          // cfg.extra.settings
        );
      }
      // cfg.extraModules; # keep legacy top-level extra modules for compatibility

      style = baseStyle + (cfg.extra.style or "") + (cfg.extraModulesStyle or "");
    };
  };
}
