#!/bin/bash
VERSION=$(date -r "$0" '+%Y-%m-%d')
depth="-maxdepth 1"
dry_run=""

while [ $# -gt 0 ]; do
  case "$1" in
    -r|--recursive) depth="" ;;
    -n|--dry-run) dry_run=1 ;;
    -h|--help)
      echo "Usage: $(basename "$0") [-r] [-n]"
      echo "  -r, --recursive   search subdirectories too"
      echo "  -n, --dry-run     show what would be removed without deleting"
      exit 0
      ;;
    *)
      echo "Unknown option: $1" >&2
      exit 1
      ;;
  esac
  shift
done

# colors
YEL=$'\033[1;33m'
BLU=$'\033[1;34m'
CYN=$'\033[1;36m'
WHT=$'\033[1;37m'
DIM=$'\033[2;37m'
RED=$'\033[1;31m'
RST=$'\033[0m'

progress_bar() {
  local current=$1
  local total=$2
  local width=36

  local pct filled
  if [ "$total" -eq 0 ]; then
    pct=100; filled=$width
  else
    pct=$((current * 100 / total))
    filled=$((current * width / total))
  fi
  local empty=$((width - filled))

  # Pac-Man mouth alternates open/closed
  local pac
  if (( current % 2 == 0 )); then pac="${YEL}ᗧ${RST}"; else pac="${YEL}ᗤ${RST}"; fi

  # eaten section: yellow dots
  local eaten=""
  if (( filled > 0 )); then
    eaten="${YEL}"
    for (( i=0; i<filled; i++ )); do eaten+="·"; done
    eaten+="${RST}"
  fi

  # uneaten section: dim dots with ghosts sprinkled in
  local ahead=""
  if (( empty > 0 )); then
    local ghost_positions=()
    if (( empty >= 6 )); then ghost_positions+=( $((empty / 3)) ); fi
    if (( empty >= 12 )); then ghost_positions+=( $((empty * 2 / 3)) ); fi

    ahead="${DIM}"
    for (( i=0; i<empty; i++ )); do
      local is_ghost=0
      for gp in "${ghost_positions[@]}"; do
        if (( i == gp )); then is_ghost=1; break; fi
      done
      if (( is_ghost )); then
        ahead+="${RST}${CYN}ᗣ${RST}${DIM}"
      else
        ahead+="·"
      fi
    done
    ahead+="${RST}"
  fi

  printf "\r  %s%s%s  ${WHT}%3d%%${RST} ${DIM}(%d/%d)${RST}" \
    "$eaten" "$pac" "$ahead" "$pct" "$current" "$total" >&2
}

printf "${YEL}ᗧ··ᗤ${RST}  ${WHT}dedupe${RST} ${DIM}v${VERSION}${RST}\n" >&2
printf "${DIM}  scanning...${RST}" >&2
total_files=$(find . $depth -type f | wc -l | tr -d ' ')
printf "\r${YEL}ᗧ${RST}  Hashing ${WHT}%d${RST} files...\n" "$total_files" >&2

count=0
find . $depth -type f | while IFS= read -r file; do
  count=$((count + 1))
  progress_bar "$count" "$total_files"
  md5sum "$file"
done | sort | awk -v dry_run="${dry_run:-0}" '
BEGIN { first = 1; total = 0 }

$1 != prev && prev != "" {
  count = 0
  for (i = 0; i < n; i++)
    if (i != keep) count++

  if (count > 0) {
    if (dry_run && !first) print ""
    first = 0
    for (i = 0; i < n; i++)
      if (i != keep) print f[i]
  }

  total += count
  n = 0; keep = 0
}

{
  fn = substr($0, 35)
  f[n++] = fn
  if ((fn ~ /schmeeve-AI-/ && f[keep] !~ /schmeeve-AI-/) || (fn !~ /\/ComfyUI/ && f[keep] ~ /\/ComfyUI/)) keep = n - 1
  prev = $1
}

END {
  count = 0
  for (i = 0; i < n; i++)
    if (i != keep) count++

  if (count > 0) {
    if (dry_run && !first) print ""
    for (i = 0; i < n; i++)
      if (i != keep) print f[i]
  }

  total += count

  if (dry_run)
    printf "Summary: %d duplicate file(s) found\n", total
  else
    printf "Removed %d duplicate file(s)\n", total > "/dev/stderr"
}' | if [ -n "$dry_run" ]; then
    cat
  else
    while IFS= read -r f; do rm -f "$f" 2>/dev/null; done
  fi

printf "\n" >&2
