_panel_management() {
    local cur prev words cword
    _init_completion || return

    # --- вспомогательная проверка: есть ли уже токен в строке ---
    _pm_has() {
        local needle="$1" w
        for w in "${words[@]:1}"; do
            [[ "$w" == "$needle" ]] && return 0
        done
        return 1
    }

    # --- фильтр: из строки опций убрать те, что уже введены ---
    _pm_filter() {
        local opts="$1" tok result=""
        for tok in $opts; do
            _pm_has "$tok" || result+=" $tok"
        done
        echo "$result"
    }

    local commands="help list run setup -h"

    # ---- 0. Если ждём значение опции — ничего не предлагаем ----
    # -p/-n/-c/-v требуют следующего аргумента (тип/номер/команда/значение).
    # --nextouch-ip тоже требует значения (адрес).
    case "$prev" in
        -p|--panel-type|-n|--number|-c|--cmd|-v|--value|--nextouch-ip)
            # для -p всё-таки предложим 0/1 — обрабатываем ниже отдельно
            if [[ "$prev" == "-p" || "$prev" == "--panel-type" ]]; then
                :
            else
                return
            fi
            ;;
    esac

    # ---- 1. После "-p 1" или "--panel-type 1" → предлагаем --nextouch-ip ----
    if [[ ( "$prev" == "1" ) && ( "${words[cword-2]}" == "-p" || "${words[cword-2]}" == "--panel-type" ) ]]; then
        local opts
        opts=$(_pm_filter "--nextouch-ip")
        COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
        return
    fi

    # ---- 2. После "-p"/"--panel-type" → предлагаем 0 или 1 ----
    if [[ "$prev" == "-p" || "$prev" == "--panel-type" ]]; then
        COMPREPLY=( $(compgen -W "0 1" -- "$cur") )
        return
    fi

    # ---- 3. Первый уровень: команды ----
    if [[ $cword -eq 1 ]]; then
        local opts
        opts=$(_pm_filter "$commands")
        COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
        return
    fi

    # ---- 4. Ищем, введена ли подкоманда ----
    local subcmd="" w
    for w in "${words[@]:1}"; do
        case "$w" in
            list|setup|run) subcmd="$w"; break ;;
        esac
    done

    # ---- 5. Внутри подкоманды — опции с учётом взаимоисключения и повторов ----
    if [[ -n "$subcmd" ]]; then
        # Базовый набор опций зависит от подкоманды.
        # -f имеет смысл только для setup.
        # -v имеет смысл только для run.
        local sub_opts="-p -n -c"
        case "$subcmd" in
            run)   sub_opts="-p -n -c -v" ;;
            setup) sub_opts="-p -f" ;;
            list)  sub_opts="-p" ;;
        esac

        local opts
        opts=$(_pm_filter "$sub_opts")
        COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
        return
    fi
}

complete -F _panel_management panel-management
