#!/bin/bash

# Autoclicker script for Sway
# Clicks continuously with random delays and periodic breaks
# Press ESC to stop
# Requires ydotool and ydotoold daemon running

# Configuration
MIN_DELAY=51      # Minimum delay in milliseconds
MAX_DELAY=689     # Maximum delay in milliseconds
MIN_CLICKS_BEFORE_BREAK=50   # Minimum clicks before break
MAX_CLICKS_BEFORE_BREAK=300  # Maximum clicks before break
MIN_BREAK=5        # Minimum break duration in seconds
MAX_BREAK=10       # Maximum break duration in seconds

STATE_FILE="/tmp/autoclicker_running"
LOCK_FILE="/tmp/autoclicker_lock"

# Check if ydotool is available
if ! command -v ydotool &> /dev/null; then
    echo "Error: ydotool is not installed. Install it with: sudo pacman -S ydotool"
    exit 1
fi

# Check if bc is available (needed for random delay calculation)
if ! command -v bc &> /dev/null; then
    echo "Error: bc is not installed. Install it with: sudo pacman -S bc"
    exit 1
fi

# Check if script is already running (prevent multiple instances)
if [ -f "$LOCK_FILE" ]; then
    echo "Autoclicker is already running!"
    echo "Press ESC to stop it."
    exit 0
fi

# Create lock file
echo $$ > "$LOCK_FILE"

# Clean up lock file on exit
cleanup() {
    rm -f "$LOCK_FILE"
    rm -f "$STATE_FILE"
    echo ""
    echo "Autoclicker stopped."
}
trap cleanup EXIT INT TERM

# Check if ydotoold daemon is running
if ! pgrep -x "ydotoold" > /dev/null; then
    echo "Starting ydotoold daemon..."
    sudo ydotoold &
    sleep 1
fi

# Create state file to indicate running
echo "running" > "$STATE_FILE"

# Function to generate random delay in seconds
get_random_delay() {
    local min=$1
    local max=$2
    local range=$((max - min))
    local random_ms=$((min + RANDOM % (range + 1)))
    echo "scale=3; $random_ms / 1000" | bc
}

# Function to generate random number of clicks before break
get_random_clicks() {
    local min=$1
    local max=$2
    local range=$((max - min))
    echo $((min + RANDOM % (range + 1)))
}

# Function to check if ESC key was pressed (by checking if state file was removed)
check_exit() {
    if [ ! -f "$STATE_FILE" ]; then
        echo "Exit signal received!"
        exit 0
    fi
}

echo "=========================================="
echo "Autoclicker started!"
echo "=========================================="
echo "Configuration:"
echo "  - Click delay: ${MIN_DELAY}-${MAX_DELAY}ms"
echo "  - Break every: ${MIN_CLICKS_BEFORE_BREAK}-${MAX_CLICKS_BEFORE_BREAK} clicks (random)"
echo "  - Break duration: ${MIN_BREAK}-${MAX_BREAK}s"
echo ""
echo "Press ESC or run: rm $STATE_FILE"
echo "=========================================="
echo ""

click_count=0
total_clicks=0
clicks_before_break=$(get_random_clicks $MIN_CLICKS_BEFORE_BREAK $MAX_CLICKS_BEFORE_BREAK)
echo "Next break will be after $clicks_before_break clicks"
echo ""

while true; do
    check_exit
    
    # Generate random delay before this click
    delay=$(get_random_delay $MIN_DELAY $MAX_DELAY)
    
    # Perform click (suppress ydotool output)
    ydotool click 0xC0 2>/dev/null
    click_count=$((click_count + 1))
    total_clicks=$((total_clicks + 1))
    
    # Convert delay to milliseconds for display
    delay_ms=$(echo "$delay * 1000" | bc | cut -d'.' -f1)
    
    # Show each click with its delay
    echo "Click #$total_clicks (delay: ${delay_ms}ms, next break in $((clicks_before_break - click_count)) clicks)"
    
    # Check if it's time for a break
    if [ $click_count -ge $clicks_before_break ]; then
        break_duration=$(get_random_delay $((MIN_BREAK * 1000)) $((MAX_BREAK * 1000)))
        echo ""
        echo "[Break] Completed $clicks_before_break clicks (total: $total_clicks). Taking a break for ${break_duration}s..."
        sleep "$break_duration"
        click_count=0
        # Generate new random click count for next cycle
        clicks_before_break=$(get_random_clicks $MIN_CLICKS_BEFORE_BREAK $MAX_CLICKS_BEFORE_BREAK)
        echo "[Resumed] Next break will be after $clicks_before_break clicks"
        echo ""
    else
        # Wait the random delay before next click
        sleep "$delay"
    fi
done
