#!/usr/bin/env bash

# Reminders without an app: transient user timers.
#
#   panama-remind add "20m" "stand up"     relative: 90s, 20m, 1h, 1h30m
#   panama-remind add "9:30" "standup"     clock time: today, or tomorrow if past
#   panama-remind list                     one line per pending reminder
#   panama-remind pick                     choose one in the launcher; cancel it
#   panama-remind cancel <unit>            cancel by unit name
#
# systemd-run carries the whole feature: the timer survives shell exit, fires
# notify-send inside the user session with its activation environment intact,
# and cleans itself up after firing. The message rides the unit Description so
# list can show it without a state file. Everything relative is converted to
# seconds first, so there is exactly one systemd-run form to get right.

set -euo pipefail

usage() {
  echo 'usage: panama-remind add "<20m|1h30m|9:30>" "<text>" | list | pick | cancel <unit>' >&2
  exit 2
}

seconds_until() {
  local when="$1" total=0 rest num unit
  if [[ "$when" =~ ^([0-9]{1,2}):([0-9]{2})$ ]]; then
    local target now
    target="$(date -d "$when" +%s 2>/dev/null)" || return 1
    now="$(date +%s)"
    (( target <= now )) && target=$(( target + 86400 ))
    echo $(( target - now ))
    return 0
  fi
  rest="$when"
  [[ "$rest" =~ ^([0-9]+[smh])+$ ]] || return 1
  while [[ "$rest" =~ ^([0-9]+)([smh])(.*)$ ]]; do
    num="${BASH_REMATCH[1]}" unit="${BASH_REMATCH[2]}" rest="${BASH_REMATCH[3]}"
    case "$unit" in
      s) total=$(( total + num ));;
      m) total=$(( total + num * 60 ));;
      h) total=$(( total + num * 3600 ));;
    esac
  done
  (( total > 0 )) || return 1
  echo "$total"
}

cmd="${1:-}"
case "$cmd" in
  add)
    when="${2:-}" text="${3:-}"
    [[ -n "$when" && -n "$text" ]] || usage
    if ! secs="$(seconds_until "$when")"; then
      notify-send "Reminder not set" "Could not read \"$when\" — try 20m, 1h30m, or 9:30" 2>/dev/null || true
      echo "panama-remind: could not parse \"$when\"" >&2
      exit 1
    fi
    unit="panama-remind-$(date +%s)-$RANDOM"
    systemd-run --user --collect --unit="$unit" \
      --description="$text" \
      --on-active="${secs}s" --timer-property=AccuracySec=1s \
      notify-send --urgency=critical --icon=alarm-symbolic "Reminder" "$text" \
      >/dev/null
    notify-send "Reminder set" "\"$text\" in $when" 2>/dev/null || true
    ;;
  list)
    # unit <TAB> when it fires <TAB> message, one per pending reminder.
    # `next` is microseconds since the epoch.
    systemctl --user list-timers 'panama-remind-*' --output=json 2>/dev/null \
      | jq -r '.[] | [.unit, ((.next // 0) / 1000000 | floor)] | @tsv' \
      | while IFS=$'\t' read -r unit next; do
          desc="$(systemctl --user show "$unit" --property=Description --value 2>/dev/null)"
          printf '%s\t%s\t%s\n' "$unit" "$(date -d "@$next" '+%H:%M:%S' 2>/dev/null)" "$desc"
        done
    ;;
  pick)
    lines="$("$0" list)"
    if [[ -z "$lines" ]]; then
      notify-send "Reminders" "Nothing pending" 2>/dev/null || true
      exit 0
    fi
    chosen="$(awk -F'\t' '{ printf "%s — %s\n", $3, $2 }' <<<"$lines" \
      | vicinae dmenu --navigation-title "Cancel a reminder" \
          --section-title 'Pending ({count})' --format index)" || exit 0
    [[ -n "$chosen" ]] || exit 0
    unit="$(sed -n "$(( chosen + 1 ))p" <<<"$lines" | cut -f1)"
    [[ -n "$unit" ]] && "$0" cancel "$unit"
    ;;
  cancel)
    unit="${2:-}"; [[ -n "$unit" ]] || usage
    systemctl --user stop "${unit%.timer}.timer" 2>/dev/null || true
    notify-send "Reminder cancelled" 2>/dev/null || true
    ;;
  *) usage;;
esac
