#!/bin/bash
APP=$1
declare -a INSTANCES

# Per-class launch commands for kitty-* (class -> command run via `kitty -e`).
# Unmapped classes just open a plain kitty with that class.
declare -A KITTY_CMDS=(
    # [kitty-lazygit]="lazygit"
    # [kitty-btop]="btop"
)

# Handle webapp cycling and launching
if [[ "$APP" == "webapp" ]]; then
    # Cycle through all WebApps
    INSTANCES=($(niri msg -j windows | jq -r '.[] | select(.app_id | startswith("WebApp-")) | .id'))
elif [[ "$APP" == webapp-* ]]; then
    # Extract the webapp name (e.g., "webapp-claude" -> "Claude")
    WEBAPP_NAME=$(echo "$APP" | sed 's/webapp-//' | sed 's/.*/\u&/')
    # Find matching WebApp by prefix (case-insensitive match)
    APP_ID=$(niri msg -j windows | jq -r ".[] | select(.app_id | test(\"WebApp-${WEBAPP_NAME}\"; \"i\")) | .app_id" | head -1)

    if [ -z "$APP_ID" ]; then
        # No instance running, launch via gtk-launch
        DESKTOP_FILE=$(find ~/.local/share/applications -name "WebApp-${WEBAPP_NAME}*.desktop" -print -quit 2>/dev/null)
        if [ -n "$DESKTOP_FILE" ]; then
            gtk-launch "$(basename "$DESKTOP_FILE")"
        else
            echo "No desktop file found for WebApp-${WEBAPP_NAME}"
        fi
        exit 0
    fi

    INSTANCES=($(niri msg -j windows | jq -r ".[] | select(.app_id | test(\"WebApp-${WEBAPP_NAME}\"; \"i\")) | .id"))
elif [[ "$APP" == "kitty" ]]; then
    # Cycle through ALL kitty windows (any class: kitty, kitty-nvim, ...)
    INSTANCES=($(niri msg -j windows | jq -r '.[] | select((.app_id // "") | ascii_downcase | startswith("kitty")) | .id'))
elif [[ "$APP" == kitty-* ]]; then
    # Specific kitty class, e.g. kitty-nvim -> app_id "kitty-nvim"
    INSTANCES=($(niri msg -j windows | jq -r --arg cls "$APP" \
        '.[] | select((.app_id // "") | ascii_downcase == ($cls | ascii_downcase)) | .id'))

    if [ ${#INSTANCES[@]} -eq 0 ]; then
        cmd="${KITTY_CMDS[$APP]:-}"
        if [ -n "$cmd" ]; then
            niri msg action spawn -- kitty --class "$APP" -e $cmd
        else
            niri msg action spawn -- kitty --class "$APP"
        fi
        exit 0
    fi
elif [[ "$APP" == "ghostty" ]]; then
    # Cycle through Ghostty terminals (case-insensitive app_id match)
    INSTANCES=($(niri msg -j windows | jq -r '.[] | select(.app_id | test("ghostty"; "i")) | .id'))
else
    INSTANCES=($(niri msg -j windows | jq -r ".[] | select(.app_id==\"${APP}\") | .id"))
fi

# Launch if no instances
if [ ${#INSTANCES[@]} -eq 0 ]; then
    # Removed "kitty" from this block so it falls through to the spawn command
    if [[ "$APP" == "webapp" || "$APP" == "ghostty" ]]; then
        echo "No ${APP} windows running"
        exit 0
    fi
    niri msg action spawn -- $APP
    exit 0
fi

# Focus logic
if [ ${#INSTANCES[@]} -eq 1 ]; then
    niri msg action focus-window --id ${INSTANCES[0]}
else
    ISORTED=($(printf "%s\n" "${INSTANCES[@]}" | sort -n))
    FOCUSED=$(niri msg -j focused-window | jq '.id')

    if [[ ! " ${ISORTED[@]} " =~ ${FOCUSED} ]]; then
        niri msg action focus-window --id ${ISORTED[0]}
    else
        new_index=0
        for i in "${!ISORTED[@]}"; do
            if [ "${ISORTED[$i]}" -eq "${FOCUSED}" ]; then
                new_index=$(( (i + 1) % ${#ISORTED[@]} ))
                break
            fi
        done
        niri msg action focus-window --id ${ISORTED[$new_index]}
    fi
fi
