# Detect bash-completion
if ! declare -F _comp_compgen_filedir &>/dev/null; then
    echo "No function _comp_compgen_filedir found. Please install bash-completion first."
    exit 1
fi

eval "function __bak_comp_compgen_filedir() { $(declare -f _comp_compgen_filedir | tail -n +2) }"
eval "function __bak_comp_compgen_filedir_xspec() { $(declare -f _comp_compgen_filedir_xspec | tail -n +2) }"
eval "function __bak_comp_complete_minimal() { $(declare -f _comp_complete_minimal | tail -n +2) }"
eval "function __bak_comp_expand_glob() { $(declare -f _comp_expand_glob | tail -n +2) }"

# replace _comp_compgen_filedir
_comp_compgen_filedir() {
    __bak_comp_compgen_filedir "$@"
    _pinyin_completion "$@"
}

_comp_compgen_filedir_xspec() {
    __bak_comp_compgen_filedir_xspec "$@"
    _pinyin_completion "$@"
}

_comp_complete_minimal() { 
    __bak_comp_complete_minimal "$@"
    _pinyin_completion "$@"
}

_comp_expand_glob() {
    __bak_comp_expand_glob "$@"
    _pinyin_completion "$@"
}

_pinyin_completion() {
    # Check COMP_WORDS existence
    if [ ${#COMP_WORDS[@]} -eq 0 ] || [ -z "${COMP_CWORD+x}" ]; then
        return
    fi
    
    if [ -z "$(which bash-pinyin-completion)" ]; then
      return
    fi

    local cur="${COMP_WORDS[COMP_CWORD]}"

    # Detect "~/"
    local homeStart
    if [ "${cur:0:2}" = "~/" ]; then
        homeStart=true
    else
        homeStart=false
    fi

    # ignore empty
    [ -z "$cur" ] && return

    _expand || return 0

    # compgen options
    local compgen_opts=(-f)
    [[ "${1-}" == -d ]] && compgen_opts=(-d)

    # Main part
    local -a pinyin_matched
    if [[ "${compgen_opts[0]}" == -d ]]; then
        readarray -t pinyin_matched < <(bash-pinyin-completion "$cur" "-d")
    else
        readarray -t pinyin_matched < <(bash-pinyin-completion "$cur" "-f")
        if [ ${#pinyin_matched[@]} -ne 0 ]; then
            compopt -o filenames 2>/dev/null
        fi
    fi

    # merge result
    local -a old_candidates=("${COMPREPLY[@]}")
    COMPREPLY=("${old_candidates[@]}" "${pinyin_matched[@]}")
    
    declare -A seen
    local -a unique_compreply=()
    for item in "${COMPREPLY[@]}"; do
        if [[ -z "${seen[$item]}" ]]; then
            seen["$item"]=1
            unique_compreply+=( "$item" )
        fi
    done
    COMPREPLY=( "${unique_compreply[@]}" )

    if [[ "$homeStart" == true ]]; then
        local home="$HOME"
        for i in "${!COMPREPLY[@]}"; do
            case "${COMPREPLY[$i]}" in
                "$home"/*)
                    COMPREPLY[$i]="~${COMPREPLY[$i]#"$home"}"
                    ;;
            esac
        done
    fi
}
