#!/usr/bin/env bash
# description: Synthetic keyboard/mouse input via ydotool (Wayland) or xdotool (X11). Args: <key|type|click|move|scroll> [args...]
set -euo pipefail

cmd="${1:?usage: gui_input <key|type|click|move|scroll> [args...]}"
shift

# Detect input method: prefer ydotool (Wayland-safe), fall back to xdotool
if command -v ydotool &>/dev/null; then
    INPUT_TOOL="ydotool"
elif command -v xdotool &>/dev/null; then
    INPUT_TOOL="xdotool"
else
    echo "ERROR: install ydotool (Wayland) or xdotool (X11)" >&2
    exit 1
fi

case "$cmd" in
    key)
        # Simulate key press. Examples: "Return", "ctrl+c", "alt+F4", "super"
        keys="${1:?usage: gui_input key <key_combo>}"
        if [ "$INPUT_TOOL" = "ydotool" ]; then
            # ydotool uses key codes; map common names
            ydotool key "$keys"
        else
            xdotool key "$keys"
        fi
        echo "key: $keys"
        ;;
    type)
        # Type a string
        text="${1:?usage: gui_input type <text>}"
        if [ "$INPUT_TOOL" = "ydotool" ]; then
            ydotool type -- "$text"
        else
            xdotool type --clearmodifiers -- "$text"
        fi
        echo "typed: ${#text} chars"
        ;;
    click)
        # Mouse click. Args: [button] [x y]
        button="${1:-1}"  # 1=left, 2=middle, 3=right
        if [ $# -ge 3 ]; then
            x="$2"; y="$3"
            if [ "$INPUT_TOOL" = "ydotool" ]; then
                ydotool mousemove --absolute "$x" "$y"
                sleep 0.05
                ydotool click "$button"
            else
                xdotool mousemove "$x" "$y"
                sleep 0.05
                xdotool click "$button"
            fi
            echo "click: button=$button at $x,$y"
        else
            if [ "$INPUT_TOOL" = "ydotool" ]; then
                ydotool click "$button"
            else
                xdotool click "$button"
            fi
            echo "click: button=$button at cursor"
        fi
        ;;
    move)
        # Move mouse. Args: <x> <y> [--relative]
        x="${1:?usage: gui_input move <x> <y> [--relative]}"
        y="${2:?usage: gui_input move <x> <y> [--relative]}"
        relative="${3:-}"
        if [ "$INPUT_TOOL" = "ydotool" ]; then
            if [ "$relative" = "--relative" ]; then
                ydotool mousemove -- "$x" "$y"
            else
                ydotool mousemove --absolute "$x" "$y"
            fi
        else
            if [ "$relative" = "--relative" ]; then
                xdotool mousemove_relative "$x" "$y"
            else
                xdotool mousemove "$x" "$y"
            fi
        fi
        echo "moved: $x,$y${relative:+ (relative)}"
        ;;
    scroll)
        # Scroll. Args: <up|down|left|right> [amount]
        direction="${1:?usage: gui_input scroll <up|down|left|right> [amount]}"
        amount="${2:-3}"
        if [ "$INPUT_TOOL" = "ydotool" ]; then
            case "$direction" in
                up)    ydotool mousemove --wheel -- 0 "-$amount" ;;
                down)  ydotool mousemove --wheel -- 0 "$amount" ;;
                left)  ydotool mousemove --wheel -- "-$amount" 0 ;;
                right) ydotool mousemove --wheel -- "$amount" 0 ;;
            esac
        else
            case "$direction" in
                up)    xdotool click --repeat "$amount" 4 ;;
                down)  xdotool click --repeat "$amount" 5 ;;
                left)  xdotool click --repeat "$amount" 6 ;;
                right) xdotool click --repeat "$amount" 7 ;;
            esac
        fi
        echo "scroll: $direction $amount"
        ;;
    *)
        echo "usage: gui_input <key|type|click|move|scroll> [args...]" >&2
        echo "" >&2
        echo "Commands:" >&2
        echo "  key <combo>              - press key combo (e.g. ctrl+c, Return, alt+F4)" >&2
        echo "  type <text>              - type a string" >&2
        echo "  click [btn] [x y]        - mouse click (1=left 2=mid 3=right)" >&2
        echo "  move <x> <y> [--relative] - move cursor" >&2
        echo "  scroll <dir> [amount]    - scroll (up/down/left/right)" >&2
        exit 1
        ;;
esac
