#!/usr/bin/env bash

DEBUG_LOG="/tmp/pinyin_completion_debug.log"
rm -f "$DEBUG_LOG"
touch "$DEBUG_LOG"

debug() {
    echo "[$(date +%T.%N)] $*" >> "$DEBUG_LOG"
}
debug "Debug Session:"

# 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) }"

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

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

_pinyin_completion() {
    local cur="${COMP_WORDS[COMP_CWORD]}"
    
    # ignore empty
    [ -z "$cur" ] && return

     _expand || return 0

    if [[ "${cur:0:1}" == "'" || "${cur:0:1}" == "\"" ]]; then
        local dirpart="$(dirname -- "${cur:1}")"
        local basepart="$(basename -- "${cur:1}")"
    else
        local dirpart="$(dirname -- "$cur")"
        local basepart="$(basename -- "$cur")"
    fi

    debug "After extracting: dirpart='$dirpart', basepart='$basepart', cur='$cur'"
    
    # realpath resolve current path as ".", if user did not enter "./" then ignore.
    [[ "$dirpart" == "." && "${cur:0:2}" != "./" ]] && dirpart=""
    debug "Adjusted dirpart: '$dirpart'"

    local savedPWD="$PWD"
    local resolved_dir
    local compgen_opts=(-f)
    [[ "${1-}" == -d ]] && compgen_opts=(-d)

    if [[ -n "$dirpart" ]]; then
        resolved_dir="$(realpath -- "$dirpart" 2>/dev/null)"
        debug "resolved_dir: '$resolved_dir'"
        if [[ -d "$resolved_dir" ]]; then
            cd -- "$resolved_dir" 2>/dev/null || return
        else
            cd "$savedPWD" || return
            return
        fi
    fi

    local -a pinyin_matched
    if [[ "${compgen_opts[0]}" == -d ]]; then
        mapfile -t pinyin_matched < <(
            compgen -d -- |
            bash-pinyin-completion "$basepart" 2>/dev/null
            )
    else
        mapfile -t pinyin_matched < <(
            compgen -f -- |
            bash-pinyin-completion "$basepart" 2>/dev/null
        )
        if [ ${#pinyin_matched[@]} -ne 0 ]; then
            compopt -o filenames 2>/dev/null
        fi
    fi
    debug "Before join, pinyin_matched: $(declare -p pinyin_matched)"
    if [[ -n "$dirpart" ]]; then
        local sep="/"
        # dirpart is root
        if [[ "$dirpart" == "/" ]]; then
            sep=""
        fi
        
        for i in "${!pinyin_matched[@]}"; do
            debug "Before join: pinyin_matched[$i]='${pinyin_matched[$i]}'"
            pinyin_matched[$i]="${dirpart}${sep}${pinyin_matched[$i]}"
            debug "After join: pinyin_matched[$i]='${pinyin_matched[$i]}'"
        done
    fi

    cd "$savedPWD" || return
    # merge result
    debug "Final COMPREPLY before merge: $(declare -p COMPREPLY)"
    local -a old_candidates=("${COMPREPLY[@]}")
    COMPREPLY=("${old_candidates[@]}" "${pinyin_matched[@]}")
    debug "Final COMPREPLY after merge: $(declare -p COMPREPLY)"

    debug "Final COMPREPLY before deduplication: $(declare -p COMPREPLY)"
    # mapfile -t COMPREPLY < <(printf "%s\n" "${COMPREPLY[@]}" | awk '!seen[$0]++')
    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[@]}" )
    debug "Final COMPREPLY after deduplication: $(declare -p COMPREPLY)"
    

    # # fix space postfix
    # if ((${#COMPREPLY[@]} == 1)) && [[ ${COMPREPLY[0]} != */ ]]; then
    #     compopt -o nospace 2>/dev/null
    # fi
}
