_print_search() {
    if [ -z "$SEARCH_RESULTS" ]
    then
        echo "No search results found."
        return
    # else if number of search files is > 50, print "Too many search results. Please narrow your search."
    elif [ ${#SEARCH_RESULTS[@]} -gt 50 ]
    then
        echo "Found ${#SEARCH_RESULTS[@]} search results."
        echo "Too many search results. Please consider narrowing your search."
        return
    fi
    export CURRENT_FILE=$(realpath ${SEARCH_FILES[$SEARCH_INDEX]})
    export CURRENT_LINE=${SEARCH_RESULTS[$SEARCH_INDEX]}
    echo "[Result "$(jq -n "($SEARCH_INDEX + 1)")"/${#SEARCH_RESULTS[@]} (Line $CURRENT_LINE)]"
    _constrain_line  # reset CURRENT_LINE if it is out of bounds
    _print
}

# @yaml
# signature: search <search_term> [<file_path>]
# docstring: searches for the given (case sensitive) string in the specified file or the open file
# arguments:
#   search_term:
#     type: string
#     description: the term to search for
#     required: true
#   file_path:
#     type: string
#     description: the file to search in (if not provided, searches in the current open file)
#     required: false
search() {
    if [ $# -lt 1 ] || [ $# -gt 2 ]; then
        echo "Usage: search <term> [<file_path>]"
        return
    fi

    search_term="$1"
    file_path="$2"

    if [ -z "$file_path" ]; then
        if [ -z "$CURRENT_FILE" ]; then
            echo "No file open. Provide a file path or use the open command first."
            return
        fi
        file_path="$CURRENT_FILE"
    fi

    if [ ! -f "$file_path" ]; then
        echo "The given file does not exist: $file_path"
        return
    fi

    export SEARCH_FILES=( $(grep -nIH "$search_term" "$file_path" | cut -d: -f1) )
    export SEARCH_RESULTS=( $(grep -nIH "$search_term" "$file_path" | cut -d: -f2) )
    export SEARCH_INDEX=0
    _print_search
}

# @yaml
# signature: search_all <string> [<directory>]
# docstring: searches for the given (case sensitive) string in all files in the specified directory (or the current working directory)
# arguments:
#   search_term:
#     type: string
#     description: the term to search for
#     required: true
#   directory:
#     type: string
#     description: the directory to search in (if not provided, searches in the current working directory)
#     required: false
search_all() {
    if [ $# -lt 1 ] || [ $# -gt 2 ]; then
        echo "Usage: search_all <term> [<directory>]"
        return
    fi

    search_term="$1"
    directory="$2"

    if [ -z "$directory" ]; then
        # Use current directory if not provided
        directory="."
    fi

    if [ ! -d "$directory" ]; then
        # Check that the directory exists
        echo "The given directory does not exist: $directory"
        return
    fi

    export SEARCH_FILES=( $(grep -rnIH "$search_term" "$directory" | cut -d: -f1) )
    export SEARCH_RESULTS=( $(grep -rnIH "$search_term" "$directory" | cut -d: -f2) )
    export SEARCH_INDEX=0
    _print_search
}

# @yaml
# signature: next
# docstring: moves to the next search result
next() {
    if [ -z "$CURRENT_FILE" ]
    then
        echo "No file open. Use the open command first."
        return
    fi
    export SEARCH_INDEX=$(jq -n "($SEARCH_INDEX + 1) % ([${#SEARCH_RESULTS[@]}, 1] | max)")
    _print_search
}

# @yaml
# signature: prev
# docstring: moves to the previous search result
prev() {
    if [ -z "$CURRENT_FILE" ]
    then
        echo "No file open. Use the open command first."
        return
    fi
    export SEARCH_INDEX=$(jq -n "($SEARCH_INDEX - 1) % ([${#SEARCH_RESULTS[@]}, 1] | max)")
    _print_search
}
