# shellcheck shell=dash disable=SC2016

# @gemini -a file -t 0 -p
# Enter into REPL mode
# Input prompt
# Summarize
# Translate
# EXIT

# Envrionment ...
# ___X_CMD_CHAT_CURRENT_ATTCHMENT_LIST=""
# ___X_CMD_CHAT_CURRENT_SESSION=""
___x_cmd_chat___repl(){
    local session="$1"
    [ -z "$session" ] || set -- --session "$session"
    ___x_cmd_chat___exec --send "$@"
}


___x_cmd_chat___exec_repl(){
    local op="$1"
    [ "$#" -gt 0 ] || op=--app
    case "$op" in
        --start|--previous|--select|--app)
            shift; ___x_cmd_chat___exec_repl___"${op#--}" "$@" ;;
        *)  N=chat M="Not such option" log:ret:64 ;;
    esac
}

___x_cmd_chat___exec_repl___app(){
    ___x_cmd_runmode_allow_manual || N=chat M="Repl can only be used in an interactive environment" log:ret:1
    if [ -z "$session" ]; then
        local x_="";local msg="";local previous=""
        ! ___x_cmd_chat___exec_repl___id_previous_ || previous="$x_"
        ___x_cmd ui select ,msg     "NEXT"                      \
                "Start a new conversation"                              \
                ${previous:+"Continue using previous conversation -> $previous"} \
                "Interactive selection of previous conversation"           \
                "return 0"
        case "$msg" in
            Start*)     ___x_cmd_chat___exec_repl___start       "$@" ;;
            Continue*)  ___x_cmd_chat___exec_repl___previous    "$@" ;;
            Interactive*)
                        ___x_cmd_chat___exec_repl___select      "$@" ;;
            *)          return 0 ;;
        esac
    else
        ___x_cmd_chat___exec_repl_loop "$@"
    fi
}

___x_cmd_chat___exec_repl___start(){
    local x_=""; ___x_cmd_chat___exec_repl___id_ || return $?
    local session="$x_"
    ___x_cmd_chat___exec_repl_loop "$@"
}

___x_cmd_chat___exec_repl___previous(){
    local x_=""; ___x_cmd_chat___exec_repl___id_previous_ || return $?
    local session="$x_"
    ___x_cmd_chat___exec_repl_loop "$@"
}

___x_cmd_chat___exec_repl___select(){
    local x_=""; ___x_cmd_chat___exec_repl___id_previous_app_ || return $?
    local session="$x_"
    ___x_cmd_chat___exec_repl_loop "$@"
}

# x ls | @ -a 'work.note' --> Save to the llm results ...

___x_cmd_chat___exec_repl_loop(){
    trap ':' INT
    chat:info "repl [session=$session]"

    local history_num="${history_num:-"$def_histnum"}"
    local ___X_CMD_MD_LLM_LESS_DISABLE=1
    local x_=""
    local question="$*"

    x_=; ___x_cmd_chat___exec_repl___session_runid_ "$session"
    local run_id="$x_";

    while true; do
        printf "[%s] %s\n" "$session"  "$run_id" >"$___X_CMD_DEVTTY_FP"
        x_=; ___x_cmd_chat___exec_repl___ted_ "$question" || break
        printf "\033[1;7m>>> %s \033[0m\n" "$x_" > "$___X_CMD_DEVTTY_FP"

        ___x_cmd_chat___exec_repl____handlecmd_

        case "$x_" in
            EXIT)       break ;;
            CONT)       continue ;;
        esac
    done

    # store the default session value ...
    chat:info \
        --tip1 "resume the session -> @ -s $session" \
        --tip2 "resume the session -> @ -s -" \
        "Exit Session -> $session"
}

# show all of the help ...
___x_cmd_chat___exec_repl___printhelp(){
    ___x_cmd_chat___exec_repl_shortcut___printhelp | \
        ___x_cmd awk0 -f "$___X_CMD_ROOT_MOD/chat/lib/awk/repl_help.awk" >"$___X_CMD_DEVTTY_FP"
}

___x_cmd_chat___exec_repl___nexthelp(){
    local id=""
    ___x_cmd ui select id   "Next"                  \
        "/h         | show help"                    \
        "/exit      | exit the loop"                \
        "...        | continue the loop"
    case "$id" in
        1)      ___x_cmd_chat___exec_repl___printhelp ;;
        2)      x_=EXIT;    return 0 ;;
        4)      x_=CONT;    return 0 ;;
    esac
}

___x_cmd_chat___exec_repl____handlecmd_(){
    local attach_text=""
    case "$x_" in
        # /attach)   add attachment to the list ;
        # /rm)       remove attachment from the list ;;

        /h|/help)       ___x_cmd_chat___exec_repl___printhelp ;;
        /exit|/quit)    x_=EXIT;    return 0 ;;
        "")             ___x_cmd_chat___exec_repl___nexthelp; return ;;
        /history)       ___x_cmd_chat___exec_repl_history app   ;;
        /export)        ___x_cmd_chat___exec_repl____export "$session" ;;
        /compact)       ___x_cmd coco histsum "$session" ;;
        !*)
                        chat:info "Execute the command —> ${x_#'!'}"
                        eval "${x_#'!'}"
                        ;;
        *)
                        if ___x_cmd_chat_slash_prompt_ "$x_"; then
                            attach_text="$x_"
                            x_=""
                        else
                            ___x_cmd_chat___exec_repl_history add "$x_"
                        fi

                        is_silent=1
                        ___x_cmd_chat___exec_raw "$x_" "$history_num" "$attach_text" || {
                            chat:debug "Execution failed"
                            x_=CONT;    return 0
                        }
                        run_id=$(( run_id + 1 ))
    esac

    x_=""
}

___x_cmd_chat___exec_repl____export(){
    local session="$1"
    [ -n "$session" ] || N=chat M="Please provide session id" log:ret:64
    local scope=""
    local method=""
    while [ "$#" -gt 0 ]; do
        case "$1" in
            last|all)   scope="$1"; shift ;;
            clip|file)  method="$1"; shift ;;
            *)          break ;;
        esac
    done

    local cmd=""
    if [ -z "$scope" ]; then
        ___x_cmd ui select ,cmd "Select export content" \
            "all:   All conversation content" \
            "last:  Last conversation content" || return $?
        scope="${cmd%%:*}"
    fi

    if [ -z "$method" ]; then
        ___x_cmd ui select ,cmd "Select export method" \
            "clip:  Copy to clipboard" \
            "file:  Save to file" || return $?
        method="${cmd%%:*}"
    fi

    case "$method" in
        clip)
            ___x_cmd_chat___exec_repl____export_raw "$session" "$scope" | ___x_cmd pb c
            chat:info "Conversation exported to clipboard"
            ;;
        file)
            local fp=""
            ___x_cmd tui form --ctrl_exit_strategy fp "File path:" "$PWD/content.txt" || return $?
            [ -n "$fp" ] || return $?
            ___x_cmd_cmds touch "$fp" || return $?
            ___x_cmd_chat___exec_repl____export_raw "$session" "$scope" > "$fp" || return $?
            chat:info "Conversation exported to file -> $fp"
            ;;
    esac
}

___x_cmd_chat___exec_repl____export_raw(){
    local session="$1"
    local scope="${2:-"all"}"

    local session_dir="$___X_CMD_CHAT_SESSION_DIR/$session"
    chat:debug --session_dir "$session_dir" "export session conversation content"
    [ -d "$session_dir" ] || {
        chat:warn "Not found conversation content"
        return 1
    }

    local l=""; local dir=""; local reqfile=""; local resfile=""
    { ___x_cmd find --cmd "$session_dir" -type f -path "*/chat.response/done" | ___x_cmd_cmds sort -r; } | {
        while read -r l; do
            printf "%s\n" "$l"
            dir="${l%"/chat.response/done"}"
            reqfile="$dir/chat.request/question"
            if [ -f "$reqfile" ]; then
                printf "%s\n" "$reqfile"
                [ "$scope" != "last" ] || break
            fi
        done
    } | ___x_cmd_cmds sort | {
        while read -r l; do
            case "$l" in
                *chat.request/question)
                    printf ">>> %s\n\n" "$( ___x_cmd_cmds cat "$l" )" ;;
                *)
                    dir="${l%"/chat.response/done"}"
                    resfile="$dir/chat.response/content"
                    [ ! -f "$resfile" ] || printf "%s\n\n" "$( ___x_cmd_cmds cat "$resfile" )"
                    ;;
            esac
        done
    }
}
