#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
HYPR_DIR="$(cd -- "$SCRIPT_DIR/.." && pwd)"
WALLPAPER_DIR="${WALLPAPER_DIR:-$HOME/Bilder/Wallpaper}"
HYPRPAPER_CONF="$HYPR_DIR/hyprpaper.conf"
CURRENT_WALLPAPER="$HYPR_DIR/current-wallpaper"

TRANSITION_TYPE="${TRANSITION_TYPE:-grow}"
TRANSITION_DURATION="${TRANSITION_DURATION:-1.0}"
TRANSITION_FPS="${TRANSITION_FPS:-60}"
TRANSITION_POS="${TRANSITION_POS:-center}"

notify() {
    notify-send "󰸉 Wallpaper" "$1" >/dev/null 2>&1 || true
}

start_detached() {
    local command_name="$1"
    local unit_name="${command_name//[^[:alnum:]_.-]/-}"

    if command -v systemd-run >/dev/null 2>&1; then
        systemd-run --user --unit="$unit_name" --collect "$@" >/dev/null 2>&1 && return
    fi

    if command -v setsid >/dev/null 2>&1; then
        setsid -f "$@" >/dev/null 2>&1
    else
        "$@" >/dev/null 2>&1 &
    fi
}

apply_wallpaper() {
    local wallpaper="$1"

    cat >"$HYPRPAPER_CONF" <<EOF
wallpaper {
	monitor =
	path = $wallpaper
	fit_mode = cover
}
EOF

    printf '%s\n' "$wallpaper" >"$CURRENT_WALLPAPER"

    if command -v awww >/dev/null 2>&1; then
        if ! pgrep -x awww-daemon >/dev/null 2>&1; then
            start_detached awww-daemon
            sleep 0.2
        fi

        awww img "$wallpaper" \
            --transition-type "$TRANSITION_TYPE" \
            --transition-duration "$TRANSITION_DURATION" \
            --transition-fps "$TRANSITION_FPS" \
            --transition-pos "$TRANSITION_POS" >/dev/null 2>&1 || true
        return
    fi

    if command -v swww >/dev/null 2>&1; then
        if ! pgrep -x swww-daemon >/dev/null 2>&1; then
            start_detached swww-daemon
            sleep 0.2
        fi

        swww img "$wallpaper" \
            --transition-type "$TRANSITION_TYPE" \
            --transition-duration "$TRANSITION_DURATION" \
            --transition-fps "$TRANSITION_FPS" \
            --transition-pos "$TRANSITION_POS" >/dev/null 2>&1 || true
        return
    fi

    if command -v hyprctl >/dev/null 2>&1; then
        if ! pgrep -x hyprpaper >/dev/null 2>&1; then
            start_detached hyprpaper
            sleep 0.2
        fi

        hyprctl hyprpaper preload "$wallpaper" >/dev/null || true
        hyprctl hyprpaper wallpaper ",$wallpaper" >/dev/null || true
    fi
}

preview_wallpaper() {
    local wallpaper="$1"

    if command -v swayimg >/dev/null 2>&1; then
        start_detached swayimg "$wallpaper"
        return
    fi

    if command -v imv >/dev/null 2>&1; then
        start_detached imv "$wallpaper"
        return
    fi

    if command -v kitty >/dev/null 2>&1; then
        start_detached kitty \
            --class wallpaper-preview \
            --title "Wallpaper Vorschau" \
            sh -c 'clear; printf "%s\n\n" "$1"; kitty +kitten icat --fit both --align center "$1"; printf "\nEnter schliesst die Vorschau."; read -r _' \
            sh "$wallpaper"
        return
    fi

    notify "Kein Vorschauprogramm gefunden."
}

if [[ "${1:-}" == "--apply" ]]; then
    wallpaper="${2:-}"

    if [[ -z "$wallpaper" || ! -f "$wallpaper" ]]; then
        notify "Wallpaper nicht gefunden."
        exit 1
    fi

    apply_wallpaper "$wallpaper"
    notify "$(basename "$wallpaper") angewendet."
    exit 0
fi

if [[ "${1:-}" == "--preview" ]]; then
    wallpaper="${2:-}"

    if [[ -z "$wallpaper" || ! -f "$wallpaper" ]]; then
        notify "Wallpaper nicht gefunden."
        exit 1
    fi

    preview_wallpaper "$wallpaper"
    exit 0
fi

pick_wallpaper() {
    local entries=()
    local wallpaper

    mapfile -t wallpapers < <(
        find "$WALLPAPER_DIR" -maxdepth 1 -type f \
            \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' -o -iname '*.gif' \) |
            sort
    )

    if ((${#wallpapers[@]} == 0)); then
        notify "Keine Bilder in $WALLPAPER_DIR gefunden."
        exit 1
    fi

    for wallpaper in "${wallpapers[@]}"; do
        entries+=("󰸉  $(basename "$wallpaper")")
    done

    choice="$(
        printf '%s\n' "${entries[@]}" |
            wofi --dmenu --prompt "󰸉  Wallpaper" --insensitive
    )"

    [[ -z "${choice:-}" ]] && exit 0

    for i in "${!entries[@]}"; do
        if [[ "$choice" == "${entries[$i]}" ]]; then
            printf '%s\n' "${wallpapers[$i]}"
            return
        fi
    done
}

while true; do
    wallpaper="$(pick_wallpaper)"
    [[ -z "${wallpaper:-}" ]] && exit 0

    action="$(
        printf '%s\n' \
            "󰋩  Vorschau" \
            "󰄬  Anwenden" \
            "󰁍  Zurueck" |
            wofi --dmenu --prompt "󰸉  $(basename "$wallpaper")" --insensitive
    )"

    case "$action" in
        *"Vorschau"*)
            preview_wallpaper "$wallpaper"
            ;;
        *"Anwenden"*)
            apply_wallpaper "$wallpaper"
            notify "$(basename "$wallpaper") angewendet."
            exit 0
            ;;
        *"Zurueck"*)
            ;;
        *)
            exit 0
            ;;
    esac
done
