#!/usr/bin/env bash
# Capture an area, active monitor, or all monitors and edit in Satty.
set -euo pipefail
umask 077

fail() {
    echo "ferese-screenshot: $*" >&2
    if command -v notify-send >/dev/null; then
        notify-send --app-name=Ferese --urgency=critical 'Screenshot failed' "$*" || true
    fi
    exit 1
}

mode=area
case ${1:-} in
    '') ;;
    --full) mode=full; shift ;;
    --all) mode=all; shift ;;
    --help|-h)
        echo 'Usage: ferese-screenshot [--full | --all]'
        echo 'Select an area; --full captures the active monitor; --all captures all monitors.'
        exit 0
        ;;
    *) fail 'Usage: ferese-screenshot [--full | --all]' ;;
esac
(($# == 0)) || fail 'Usage: ferese-screenshot [--full | --all]'

for tool in feresectl satty wl-copy flock python3; do
    command -v "$tool" >/dev/null || fail "Required command not found: $tool"
done
: "${XDG_RUNTIME_DIR:?A Wayland login session is required}"
exec 9>"$XDG_RUNTIME_DIR/ferese-screenshot.lock"
flock -n 9 || exit 0

capture_args=()
if [[ $mode == area ]]; then
    command -v slurp >/dev/null || fail 'Required command not found: slurp'
    # Escape cancels without creating a file or changing the clipboard.
    geometry=$(slurp) || exit 0
    [[ -n $geometry ]] || exit 0
    capture_args=(-g "$geometry")
elif [[ $mode == full ]]; then
    # Resolve the active monitor before Satty can change keyboard focus.
    # Never fall back to an all-monitor capture when IPC is unavailable.
    geometry=$(feresectl get-outputs | python3 -c '
import json, sys
outputs = [output for output in json.load(sys.stdin) if output.get("enabled")]
focused = [output for output in outputs if output.get("focused")]
selected = focused if len(focused) == 1 else outputs if len(outputs) == 1 else []
if len(selected) != 1 or any(selected[0].get(k) is None for k in ("x", "y", "width", "height")):
    sys.exit(1)
print("%d,%d %dx%d" % (selected[0]["x"], selected[0]["y"], selected[0]["width"], selected[0]["height"]))
') || fail 'Could not determine the active monitor. Use area selection or --all.'
    capture_args=(-g "$geometry")
fi
pictures=$(xdg-user-dir PICTURES 2>/dev/null) || pictures="$HOME/Pictures"
directory=${pictures:-$HOME/Pictures}/Screenshots
mkdir -p -- "$directory" || fail 'Could not create the screenshot directory.'
file=$(mktemp "$directory/Screenshot-$(date +%Y-%m-%d_%H-%M-%S)-XXXXXX.png") || fail 'Could not create the screenshot file.'
input=''
trap '[[ -z $input ]] || rm -f -- "$input"; [[ -s $file ]] || rm -f -- "$file"' EXIT
input=$(mktemp "$XDG_RUNTIME_DIR/ferese-screenshot-XXXXXX.png") || fail 'Could not create the temporary capture.'
feresectl screenshot "${capture_args[@]}" >"$input" || fail 'Could not capture the screen. Ferese must be running, unlocked, and reachable over its socket.'
editor_size=$(feresectl get-outputs | python3 -c '
import json, sys

outputs = [output for output in json.load(sys.stdin) if output.get("enabled")]
focused = [output for output in outputs if output.get("focused")]
selected = focused if len(focused) == 1 else outputs if len(outputs) == 1 else []
if len(selected) != 1 or any(selected[0].get(key) is None for key in ("width", "height")):
    sys.exit(1)

width = max(1, min(1500, round(selected[0]["width"] * 0.8)))
height = max(1, min(920, round(selected[0]["height"] * 0.8), round(width * 0.68)))
print(f"{width}x{height}")
') || editor_size=1000x700
# Enter saves the annotated image and copies it; Escape discards the capture.
# Keep the parent lock through editing. Close it only in Satty so clipboard
# helpers cannot inherit the lock and keep later screenshots blocked.
satty --filename "$input" --output-filename "$file" \
    --app-id dev.ferese.Screenshot \
    --resize "$editor_size" \
    --no-window-decoration \
    --copy-command 'wl-copy --type image/png' \
    --save-after-copy \
    --actions-on-enter save-to-file,save-to-clipboard,exit \
    --actions-on-escape exit 9>&- || fail 'Could not open the screenshot in Satty.'
if [[ -s $file ]]; then
    printf '%s\n' "$file"
fi
