#!/bin/bash
# Runs in each session's "claude" window. Resumes the conversation recorded for
# this session (see devdesk-session-hook), starts a fresh one if there is none,
# and offers a small menu whenever Claude exits so the window never just dies.
set -uo pipefail

# shellcheck source=libexec/devdesk-lib.sh
. "${DEVDESK_LIBEXEC:-/usr/lib/devdesk}/devdesk-lib.sh"

NAME=$(dd_current_session)
[ -n "$NAME" ] || dd_die "not running inside a DevDesk session"

SETTINGS="$DEVDESK_SHARE/claude-settings.json"

# Re-read /etc/devdesk/env before every Claude launch, so changes (Remote
# Control, CLAUDE_ARGS, …) apply on the next restart of Claude in a session.
reload_config() {
    dd_load_env
    CLAUDE_BIN=${CLAUDE_BIN:-claude}
    read -r -a EXTRA <<<"${CLAUDE_ARGS:-}"
}

ORANGE=$'\033[38;2;255;107;0m'
CYAN=$'\033[38;2;0;212;255m'
MUTED=$'\033[38;2;62;96;122m'
RESET=$'\033[0m'

common_args() {
    printf '%s\0' --settings "$SETTINGS"
    if [ "${DEVDESK_REMOTE_CONTROL:-0}" = "1" ]; then
        printf '%s\0' --remote-control "devdesk-$NAME"
    fi
    if [ ${#EXTRA[@]} -gt 0 ]; then
        printf '%s\0' "${EXTRA[@]}"
    fi
}

run_new() {
    local args
    mapfile -d '' args < <(common_args)
    "$CLAUDE_BIN" -n "$NAME" "${args[@]}"
}

run_resume() {
    local id args fork=()
    id=$(dd_registry_get "$NAME" claude_session_id)
    if [ -z "$id" ]; then
        run_new
        return
    fi
    # Start fresh only when the conversation's file is really gone. Any other
    # failure (an early Ctrl+C, a network error) leaves the recorded id alone
    # and ends at the menu, where ⏎ tries again (devdesk#12).
    if [ -z "$(dd_convo_file "$id")" ]; then
        printf "%sConversation %s is no longer in Claude's history — starting a new one.%s\n" "$MUTED" "$id" "$RESET"
        sleep 1
        run_new
        return
    fi
    mapfile -d '' args < <(common_args)
    # "Fork" from conversation search (devdesk#24): continue as a new
    # conversation, once; the SessionStart hook then records the new id.
    if [ "$(dd_registry_get "$NAME" fork)" = true ]; then
        fork=(--fork-session)
        # shellcheck disable=SC2016 # $n is a jq variable
        dd_registry_update 'del(.sessions[$n].fork)' --arg n "$NAME" 2>/dev/null || true
    fi
    "$CLAUDE_BIN" --resume "$id" "${fork[@]}" "${args[@]}"
}

menu() {
    printf '\n%s◈ Claude exited%s %s(session %s, code %s)%s\n' "$ORANGE" "$RESET" "$MUTED" "$NAME" "$1" "$RESET"
    printf '  %s[⏎]%s resume   %s[n]%s new conversation   %s[s]%s shell   %s[x]%s end session\n' \
        "$CYAN" "$RESET" "$CYAN" "$RESET" "$CYAN" "$RESET" "$CYAN" "$RESET"
}

printf '\033]2;%s\033\134' "$NAME" # pane title (ST = ESC \\)

# While a DevDesk tab shows this session, this marker exists and Claude tells
# Remote Control a client is present, which holds back phone pushes (devdesk#26).
# Keyed by tmux's session id, which survives renames.
sid=$(dd_tmux display -p -t "${TMUX_PANE:-}" '#{session_id}' 2>/dev/null)
if [ -n "$sid" ]; then
    export CLAUDE_CLIENT_PRESENCE_FILE="$DEVDESK_PRESENCE_DIR/${sid#\$}"
fi
mode=resume
while :; do
    NAME=$(dd_current_session) # follow renames
    reload_config
    if [ "$mode" = new ]; then run_new; else run_resume; fi
    rc=$?
    NAME=$(dd_current_session)
    while :; do
        menu "$rc"
        IFS= read -rsn1 key || exit 0
        case $key in
        "") mode=resume; break ;;
        n | N) mode=new; break ;;
        s | S)
            printf '%sShell in %s — exit to return to this menu.%s\n' "$MUTED" "$PWD" "$RESET"
            "${SHELL:-/bin/bash}" -l
            ;;
        x | X)
            printf 'End session %s? This stops Claude and forgets the session. [y/N] ' "$NAME"
            IFS= read -rsn1 confirm || exit 0
            echo
            if [ "$confirm" = y ] || [ "$confirm" = Y ]; then
                dd_registry_remove "$NAME"
                tmux kill-session -t "=$NAME" 2>/dev/null
                exit 0
            fi
            ;;
        esac
    done
done
