#!/usr/bin/env sh

set -eu

dnd_mode="do-not-disturb"

json_string() {
  if command -v jq >/dev/null 2>&1; then
    printf '%s' "$1" | jq -Rs .
    return
  fi

  printf '%s' "$1" | awk '
    BEGIN { ORS = "" }
    {
      gsub(/\\/, "\\\\")
      gsub(/"/, "\\\"")
      gsub(/\t/, "\\t")
      if (NR > 1) {
        printf "\\n"
      }
      printf "%s", $0
    }
    END { printf "\n" }
  '
}

refresh_waybar() {
  pkill -RTMIN+8 waybar >/dev/null 2>&1 || true
}

notification_count() {
  if ! command -v jq >/dev/null 2>&1; then
    printf '0'
    return
  fi

  makoctl list -j 2>/dev/null \
    | jq '[.. | objects | select(has("id"))] | length' 2>/dev/null \
    || printf '0'
}

is_dnd() {
  makoctl mode 2>/dev/null | grep -qx "$dnd_mode"
}

status() {
  if ! modes="$(makoctl mode 2>/dev/null)"; then
    text="$(json_string " n/a")"
    class="$(json_string "disabled")"
    tooltip="$(json_string "Mako is unavailable")"
    printf '{"text":%s,"class":%s,"tooltip":%s}\n' "$text" "$class" "$tooltip"
    return
  fi

  count="$(notification_count)"
  count="${count:-0}"

  if printf '%s\n' "$modes" | grep -qx "$dnd_mode"; then
    state="dnd"
    icon=""
    label="Do Not Disturb is on"
  elif [ "$count" -gt 0 ] 2>/dev/null; then
    state="active"
    icon=""
    label="Do Not Disturb is off"
  else
    state="normal"
    icon=""
    label="Do Not Disturb is off"
  fi

  text="$(json_string "$icon $count")"
  class="$(json_string "$state")"
  tooltip="$(json_string "$label
$count pending notifications
Left click toggles DND
Right click opens the notification list")"

  printf '{"text":%s,"class":%s,"tooltip":%s}\n' "$text" "$class" "$tooltip"
}

toggle() {
  makoctl mode -t "$dnd_mode" >/dev/null 2>&1 || true
  refresh_waybar
}

list_notifications() {
  title="Notifications"

  if command -v jq >/dev/null 2>&1; then
    list="$(
      makoctl list -j 2>/dev/null \
        | jq -r '
          [.. | objects | select(has("id"))]
          | if length == 0 then
              "No pending notifications"
            else
              .[]
              | [
                  (."app-name" // .app_name // "app"),
                  (.summary // ""),
                  (.body // "")
                ]
              | map(select(. != ""))
              | join(" - ")
            end
        ' 2>/dev/null
    )"
  else
    list="$(makoctl list 2>/dev/null || printf 'No pending notifications')"
  fi

  if [ -z "$list" ]; then
    list="No pending notifications"
  fi

  if command -v wofi >/dev/null 2>&1; then
    printf '%s\n' "$list" | wofi --dmenu --prompt "$title" >/dev/null 2>&1 || true
  elif command -v alacritty >/dev/null 2>&1; then
    tmp="${TMPDIR:-/tmp}/mako-notifications.$$"
    printf '%s\n' "$list" > "$tmp"
    alacritty -e sh -c 'printf "%s\n\n" "$1"; cat "$2"; printf "\nPress Enter to close."; read -r _' sh "$title" "$tmp"
    rm -f "$tmp"
  else
    printf '%s\n' "$list"
  fi
}

case "${1:-status}" in
  status) status ;;
  toggle) toggle ;;
  list) list_notifications ;;
  *) status ;;
esac
