# shellcheck shell=dash disable=SC2016

___x_cmd_jq_repl(){
    case "$1" in
        -h|--help)      ___x_cmd help -m "${___X_CMD_JQ_REPL_CMD:-jq}" repl
                                                                    return ;;
        --preview)      shift;  ___x_cmd_jq_repl___preview  "$@" ;  return ;;
        --header)       shift;  ___x_cmd_jq_repl___header   "$@" ;  return ;;
    esac

    ___x_cmd_jq_repl_app "$@"
}

___x_cmd_jq_repl_app(){
    ___x_cmd jq --preparecmd
    ___x_cmd yq --preparecmd

    local fp="$1"
    local pidofsubshell; pidofsubshell="$(___x_cmd pidofsubshell)"

    local ___X_CMD_JQ_FZF_APP_DIR=
    case "${fp}" in
        -|"")
            ___X_CMD_JQ_FZF_APP_DIR="$___X_CMD_ROOT_TMP/${___X_CMD_JQ_REPL_CMD:-jq}.${pidofsubshell}.d"
            ___x_cmd mkdirp "$___X_CMD_JQ_FZF_APP_DIR"
            ___x_cmd_cmds cat            > "$___X_CMD_JQ_FZF_APP_DIR/source"
            ;;
        *)
            [ -f "$fp" ] || M="File does not exist --> $fp" N="${___X_CMD_JQ_REPL_CMD:-jq}" log:ret:1
            ___X_CMD_JQ_FZF_APP_DIR="${fp}.${___X_CMD_JQ_REPL_CMD:-jq}.${pidofsubshell}.d"
            ___x_cmd mkdirp "$___X_CMD_JQ_FZF_APP_DIR"
            ___x_cmd_cmds cat "${fp}"    > "$___X_CMD_JQ_FZF_APP_DIR/source"
    esac

    ___x_cmd_compat_syncfs "$___X_CMD_JQ_FZF_APP_DIR/source" 2>/dev/null

    (
        trap '___x_cmd rmrf "$___X_CMD_JQ_FZF_APP_DIR";' EXIT

        local filter=.
        while true; do
            filter="$(
                ___X_CMD_JQ_FZF_APP_DIR="$___X_CMD_JQ_FZF_APP_DIR"  \
                ___X_CMD_JQ_REPL_CMD="$___X_CMD_JQ_REPL_CMD"        \
                ___X_CMD_RUNMODE="$___X_CMD_RUNMODE"                \
                ___x_cmdexe jq --fzdata "."
            )"

            [ -n "$filter" ] || return $?
            local id=
            ___x_cmd ui select id "Next for $filter"            \
                "Copy this filter to pastboard"                 \
                "Copy this part of the data to pastboard"       \
                "Print filter"                                  \
                "Print data"                                    \
                "Modify the filter"                             \
                "Exit"
            case "$id" in
                1)      printf "%s" "$filter" | ___x_cmd pb
                        return 0 ;;
                2)      ___x_cmd "${___X_CMD_JQ_REPL_CMD:-jq}" "$filter" <"$___X_CMD_JQ_FZF_APP_DIR/source" | ___x_cmd pb
                        return 0 ;;
                3)      printf "%s" "$filter"
                        return 0 ;;
                4)      ___x_cmd "${___X_CMD_JQ_REPL_CMD:-jq}" "$filter" <"$___X_CMD_JQ_FZF_APP_DIR/source"
                        return 0 ;;
                5)      continue ;;
                *)      return 0 ;;
            esac
        done
    )

}

___x_cmd_jq___fz_data(){
    ___x_cmd_jq_repl___actual "$@"
}

___x_cmd_jq_repl___actual(){
    local filter="${1:-.}"
    local fpfolder="$___X_CMD_JQ_FZF_APP_DIR"
    local repl_cmd="${___X_CMD_JQ_REPL_CMD:-jq}"

    ___X_CMD_JQ_FZF_APP_DIR="$___X_CMD_JQ_FZF_APP_DIR" ___X_CMD_JQ_REPL_CMD="$repl_cmd" \
    ___x_cmd fzf                                                                                \
        --header="<Please type $repl_cmd filter>"                                               \
        --reverse --no-info --height='80%'                                                      \
        --query="$filter" --print-query                                                         \
        --bind="change:transform-header(cat \"$fpfolder/\$(cat \"$fpfolder/header\").header\" )"     \
        --preview-window='down,99%' --preview "___x_cmdexe jq repl --preview {q} $fpfolder/source" <<A
A

}

___x_cmd_jq_repl___preview_check(){
    command awk -v res=1 '
    NR>1{
        res = 0
        exit(0)
    }
    END {
        exit(res)
    }
    '
}

___x_cmd_jq_repl___header(){
    local fp="$1";  shift
    [ ! -f "$___X_CMD_JQ_FZF_APP_DIR/res" ] || fp="$___X_CMD_JQ_FZF_APP_DIR/res"
    ___x_cmd "${___X_CMD_JQ_REPL_CMD:-jq}" -r '. | keys | join(" ")' <"$fp"
}

___x_cmd_jq_repl___preview(){
    ___x_cmd_jq_repl___preview_ "$@"
}

___x_cmd_jq_repl___preview_(){
    local str="$1"; shift
    local fp="$*"

    # In the future we could add yml mode ...
    if [ "${___X_CMD_JQ_REPL_REPVIEW_MODE:-yml}" = yml ] && [ "${___X_CMD_JQ_REPL_CMD:-jq}" = jq ]; then
        ___x_cmd_jq_repl___preview___partial(){
            ___x_cmd "${___X_CMD_JQ_REPL_CMD:-jq}" "$str" | ___x_cmd yq -C -pj -oy . | ___x_cmd_cmds head -n 1000
        }
    else
        ___x_cmd_jq_repl___preview___partial(){
            ___x_cmd "${___X_CMD_JQ_REPL_CMD:-jq}" -C "$str" | ___x_cmd_cmds head -n 1000
        }
    fi

    local md5sum; md5sum="$(___x_cmd str md5 "$str")"

    # [ ! -f "$fp.repl.jq.x-cmd.d/${md5sum}" ] || {
    #     ___x_cmd cat "$fp.repl.jq.x-cmd.d/${md5sum}"
    #     # TODO: write header
    #     return
    # }
    ___x_cmd touch "$___X_CMD_JQ_FZF_APP_DIR/history"
    if ___x_cmd tee "$___X_CMD_JQ_FZF_APP_DIR/${md5sum}" --  ___x_cmd_jq_repl___preview___partial "$str" <"$fp"; then
        if ___x_cmd_jq_repl___preview_check <"$___X_CMD_JQ_FZF_APP_DIR/${md5sum}"; then

            ___x_cmd "${___X_CMD_JQ_REPL_CMD:-jq}" "$str" <"$fp" | ___x_cmd "${___X_CMD_JQ_REPL_CMD:-jq}" -r '. | keys | join(" ")' >"$___X_CMD_JQ_FZF_APP_DIR/${md5sum}.header"
            printf "%s\n" "${md5sum}" >"$___X_CMD_JQ_FZF_APP_DIR/header"
            ___x_cmd_jq_repl___preview_history_add "$fp" "$md5sum" "$str"
            return
        fi
    else
        ___x_cmd rmrf "$___X_CMD_JQ_FZF_APP_DIR/${md5sum}"
    fi

    printf "%s\n" "${md5sum}" >"$___X_CMD_JQ_FZF_APP_DIR/header"

    ___x_cmd_jq_repl___preview_history_dump_parent_result "$fp" "$str"
}

___x_cmd_jq_repl___preview_history_add(){
    local fp="$1"
    local md5="$2"
    local query="$3"
    printf "%s  %s\n"       "$md5"  "$query" >>"$___X_CMD_JQ_FZF_APP_DIR/history"
}

___x_cmd_jq_repl___preview_history_dump_parent_result(){
    local fp="$1"
    local fail_query="$2"

    {
        printf "%s  %s\n"   "///"         "$fail_query"
        ___x_cmd_cmds cat "$___X_CMD_JQ_FZF_APP_DIR/history"
    } | ___x_cmd_cmds sort -r -k 2 | ___x_cmd_cmds awk -v q="$fail_query" -v dir="$___X_CMD_JQ_FZF_APP_DIR" '
    # {  print }
    ($0~"^///"){

        while (getline) {
            md5sum = $1
            $1 = ""
            gsub("^[ ]+", "", $0)
            if (index(q, $0) > 0) break
        }

        printf("\n=== parent filter  ->  %s\n", $0)
        if (md5sum != ""){
            while ( getline line <(dir "/" md5sum) ){  print line; }
            print md5sum > (dir "/header")
        } else {
            printf("\n=== The data format is incorrect.\n")
        }
        exit
    }
    '
}
