#!/usr/bin/env bash
# Wallpaper picker for niri using swaybg.
# Usage: wallpaper-picker [directory]

set -u

DIR="${1:-$HOME/Pictures}"
STATE_FILE="${HOME}/.config/niri-wallpaper"

IMAGES=()
while IFS= read -r -d '' f; do
    IMAGES+=("$f")
done < <(find "$DIR" -maxdepth 1 -type f \
    \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \
       -o -iname '*.webp' -o -iname '*.bmp' -o -iname '*.avif' \) \
    -print0 | sort -z)

[[ ${#IMAGES[@]} -eq 0 ]] && { echo "No images found in $DIR"; exit 1; }

INDEX=0

icat() { kitty +kitten icat --stdin=no --silent --transfer-mode=memory "$@" 2>/dev/null; }
clear_images() { icat --clear; }

draw() {
    local cols rows
    cols=$(tput cols); rows=$(tput lines)
    local n=${#IMAGES[@]}
    local prev=$(( (INDEX - 1 + n) % n ))
    local next=$(( (INDEX + 1) % n ))
    local header_h=2
    local footer_h=4
    local img_h=$(( rows - header_h - footer_h ))
    (( img_h < 5 )) && img_h=5
    local side_w=$(( cols * 18 / 100 ))
    local center_w=$(( cols - 2 * (side_w + 2) ))
    local center_x=$(( side_w + 2 ))
    local next_x=$(( center_x + center_w + 2 ))

    printf '\033[2J\033[H'
    clear_images
    tput cup 0 0
    printf '  Wallpaper Picker (niri/swaybg)  [%d/%d] %s' \
        $(( INDEX + 1 )) "$n" "$(basename "${IMAGES[$INDEX]}")"
    icat --place "${side_w}x${img_h}@0x${header_h}"             "${IMAGES[$prev]}"
    icat --place "${center_w}x${img_h}@${center_x}x${header_h}" "${IMAGES[$INDEX]}"
    icat --place "${side_w}x${img_h}@${next_x}x${header_h}"     "${IMAGES[$next]}"
    local row=$(( header_h + img_h ))
    tput cup "$row" 0
    printf '  h/←: prev  l/→: next  Enter/Space: apply  q: quit\n'
}

apply() {
    local path="$1"
    killall swaybg 2>/dev/null || true
    swaybg -m fill -i "$path" &
    printf '%s\n' "$path" > "$STATE_FILE"
    tput cup $(( $(tput lines) - 1 )) 0
    printf '\033[2K  Applied: %s' "$(basename "$path")"
}

KEY=""
read_key() {
    KEY=""
    IFS= read -rsn1 KEY
    if [[ $KEY == $'\x1b' ]]; then
        local rest=""
        IFS= read -rsn2 -t 0.1 rest || true
        KEY+="$rest"
    fi
}

old_stty=$(stty -g)
trap 'stty "$old_stty"; clear_images; tput cnorm; printf "\033[2J\033[H"' EXIT
stty -echo -icanon -icrnl min 1 time 0
tput civis

draw

while true; do
    read_key
    case "$KEY" in
        h|$'\x1b[D') INDEX=$(( (INDEX - 1 + ${#IMAGES[@]}) % ${#IMAGES[@]} )); draw ;;
        l|$'\x1b[C') INDEX=$(( (INDEX + 1) % ${#IMAGES[@]} )); draw ;;
        $'\r'|$'\n'|' ') apply "${IMAGES[$INDEX]}" ;;
        q|Q) break ;;
    esac
done
