#!/usr/bin/env bash
# toolkit module: cli/06_completion.sh
# 补全脚本生成：生成 bash/zsh 自动补全脚本

#######################################
# 生成 Bash 补全脚本
# Outputs:
#   完整的 Bash 补全脚本
#######################################
radp_cli_completion_bash() {
  local app_name="${__radp_cli_app_name:-cli}"
  local app_func="${app_name//-/_}"

  cat <<BASH_COMPLETION_HEADER
# Bash completion script for $app_name
# Generated by radp-bash-framework

BASH_COMPLETION_HEADER

  # 替换应用名
  cat <<BASH_COMPLETION_FUNC
_${app_func}() {
    local cur prev words cword

    # 兼容模式：如果 _init_completion 不存在，使用手动初始化
    if type _init_completion &>/dev/null; then
        _init_completion || return
    else
        COMPREPLY=()
        cur="\${COMP_WORDS[COMP_CWORD]}"
        prev="\${COMP_WORDS[COMP_CWORD-1]}"
        words=("\${COMP_WORDS[@]}")
        cword="\$COMP_CWORD"
    fi

    local i cmd_path=""

BASH_COMPLETION_FUNC

  # Collect all known command paths for smart cmd_path building
  local all_cmds_list
  all_cmds_list=$(__radp_cli_bash_collect_all_cmds "")

  # Build list of app global options that take values (for skipping in cmd_path builder)
  local gopts_val_list=""
  if [[ ${#__radp_cli_app_global_options_spec[@]} -gt 0 ]]; then
    local spec
    for spec in "${__radp_cli_app_global_options_spec[@]}"; do
      local -A _opt_info=()
      radp_cli_parse_option_spec "$spec" _opt_info
      if [[ "${_opt_info[has_value]}" == "true" ]]; then
        [[ -n "${_opt_info[short]}" ]] && gopts_val_list+="|-${_opt_info[short]}"
        [[ -n "${_opt_info[long]}" ]] && gopts_val_list+="|--${_opt_info[long]}"
      fi
    done
    # Remove leading |
    gopts_val_list="${gopts_val_list#|}"
  fi

  # Output the known commands list and smart cmd_path builder
  cat <<BASH_CMD_PATH_BUILDER
    # Known command paths (generated)
    local _all_cmds=" ${all_cmds_list} "

    # Build cmd_path: skip global option values, validate against known commands
    for ((i = 1; i < cword; i++)); do
        case "\${words[i]}" in
BASH_CMD_PATH_BUILDER
  if [[ -n "$gopts_val_list" ]]; then
    echo "            $gopts_val_list)"
    echo "                ((i++)) ;;"
  fi
  cat <<'BASH_CMD_PATH_BUILDER2'
            -*) ;;
            *)
                local _test_path
                if [[ -z "$cmd_path" ]]; then
                    _test_path="${words[i]}"
                else
                    _test_path="$cmd_path ${words[i]}"
                fi
                if [[ " $_all_cmds " == *" ${_test_path// /_} "* ]]; then
                    cmd_path="$_test_path"
                fi
                ;;
        esac
    done

BASH_CMD_PATH_BUILDER2

  # 生成命令补全逻辑
  echo "    # Command completions"
  echo "    case \"\$cmd_path\" in"

  # 顶级补全（包含全局选项和应用级全局选项）
  local top_commands global_opts app_global_opts
  top_commands=$(radp_cli_list_commands | tr '\n' ' ')
  global_opts="${__radp_cli_global_options:-}"
  app_global_opts="${__radp_cli_app_global_options:-}"
  echo "        '')"
  echo "            COMPREPLY=(\$(compgen -W \"$top_commands $global_opts $app_global_opts --help --version\" -- \"\$cur\"))"
  echo "            ;;"

  # 递归生成所有命令路径的补全
  __radp_cli_bash_gen_all_completions ""

  echo "        *)"
  echo "            COMPREPLY=()"
  echo "            ;;"
  echo "    esac"
  echo "}"
  echo
  echo "complete -F _${app_name//-/_} $app_name"
}

#######################################
# 递归生成 Bash 命令补全（内部函数）
# Arguments:
#   1 - parent_path: 父命令路径（空字符串表示顶级）
#######################################
__radp_cli_bash_gen_all_completions() {
  local parent_path="$1"
  local cmd_list

  if [[ -z "$parent_path" ]]; then
    cmd_list=$(radp_cli_list_commands)
  else
    cmd_list=$(radp_cli_list_subcommands "$parent_path")
  fi

  local cmd
  for cmd in $cmd_list; do
    local full_path
    if [[ -z "$parent_path" ]]; then
      full_path="$cmd"
    else
      full_path="$parent_path $cmd"
    fi

    if radp_cli_has_subcommands "$full_path"; then
      # 有子命令：补全子命令列表
      local subcommands
      subcommands=$(radp_cli_list_subcommands "$full_path" | tr '\n' ' ')
      echo "        '$full_path')"
      echo "            COMPREPLY=(\$(compgen -W \"$subcommands --help\" -- \"\$cur\"))"
      echo "            ;;"

      # 递归处理子命令
      __radp_cli_bash_gen_all_completions "$full_path"
    elif radp_cli_cmd_exists "$full_path"; then
      # 没有子命令：生成补全逻辑
      __radp_cli_bash_gen_cmd_completion "$full_path"
    fi
  done
}

#######################################
# Collect all known command paths (for smart cmd_path building)
# Outputs space-separated list of command paths with spaces replaced by _
# Arguments:
#   1 - parent_path: parent command path (empty for top-level)
#######################################
__radp_cli_bash_collect_all_cmds() {
  local parent_path="$1"
  local cmd_list

  if [[ -z "$parent_path" ]]; then
    cmd_list=$(radp_cli_list_commands)
  else
    cmd_list=$(radp_cli_list_subcommands "$parent_path")
  fi

  local cmd
  for cmd in $cmd_list; do
    local full_path
    if [[ -z "$parent_path" ]]; then
      full_path="$cmd"
    else
      full_path="$parent_path $cmd"
    fi
    echo -n "${full_path// /_} "
    if radp_cli_has_subcommands "$full_path"; then
      __radp_cli_bash_collect_all_cmds "$full_path"
    fi
  done
}

#######################################
# 生成单个命令的 Bash 补全逻辑（内部函数）
# 支持静态选项补全和动态参数/选项值补全
# Arguments:
#   1 - cmd_path: 命令路径
#######################################
__radp_cli_bash_gen_cmd_completion() {
  local cmd_path="$1"

  local -A meta=()
  if ! radp_cli_get_cmd_meta "$cmd_path" meta 2>/dev/null; then
    return
  fi

  # 包含应用级全局选项（支持命令后使用）
  local options="--help ${__radp_cli_app_global_options:-}"
  local -a opt_with_value=()
  local -A opt_complete_funcs=()

  # 始终解析选项（用于补全，与 passthrough 模式无关）
  local opt_line
  while IFS= read -r opt_line; do
    [[ -z "$opt_line" ]] && continue
    local -A opt_info=()
    radp_cli_parse_option_spec "$opt_line" opt_info
    [[ -n "${opt_info[short]}" ]] && options+=" -${opt_info[short]}"
    [[ -n "${opt_info[long]}" ]] && options+=" --${opt_info[long]}"

    # 记录需要值的选项
    if [[ "${opt_info[has_value]}" == "true" && -n "${opt_info[long]}" ]]; then
      opt_with_value+=("${opt_info[long]}")
      [[ -n "${opt_info[short]}" ]] && opt_with_value+=("${opt_info[short]}")

      # 检查是否有动态补全函数
      local complete_func
      if complete_func=$(radp_cli_get_complete_func "${opt_info[long]}" "${meta[completes]}" 2>/dev/null); then
        opt_complete_funcs["${opt_info[long]}"]="$complete_func"
        [[ -n "${opt_info[short]}" ]] && opt_complete_funcs["${opt_info[short]}"]="$complete_func"
      fi
    fi
  done <<<"${meta[options]}"

  # 解析参数的补全（静态值或动态函数）
  local -a arg_complete_funcs=()
  local -a arg_static_values=()
  local arg_line arg_idx=0
  while IFS= read -r arg_line; do
    [[ -z "$arg_line" ]] && continue
    local -A arg_info=()
    radp_cli_parse_arg_spec "$arg_line" arg_info
    # Check for static values first
    local static_values
    if static_values=$(radp_cli_get_arg_values "${arg_info[name]}" "${meta[arg_values]}" 2>/dev/null); then
      arg_static_values[$arg_idx]="$static_values"
    else
      # Check for dynamic completion function
      local complete_func
      if complete_func=$(radp_cli_get_complete_func "${arg_info[name]}" "${meta[completes]}" 2>/dev/null); then
        arg_complete_funcs[$arg_idx]="$complete_func"
      fi
    fi
    ((arg_idx++)) || true
  done <<<"${meta[args]}"

  # 计算命令路径深度（用于 arg_idx 偏移）
  local cmd_depth
  cmd_depth=$(echo "$cmd_path" | wc -w | tr -d ' ')

  # 生成补全代码
  echo "        '$cmd_path')"

  # 检查是否需要复杂的补全逻辑
  if [[ ${#opt_complete_funcs[@]} -gt 0 || ${#arg_complete_funcs[@]} -gt 0 || ${#arg_static_values[@]} -gt 0 ]]; then
    # 有动态补全或静态值：生成复杂逻辑

    # 只有当有选项动态补全时才生成 case "$prev"
    if [[ ${#opt_complete_funcs[@]} -gt 0 ]]; then
      echo "            case \"\$prev\" in"
      # 为每个有动态补全的选项生成 case
      for opt in "${!opt_complete_funcs[@]}"; do
        local func="${opt_complete_funcs[$opt]}"
        if [[ ${#opt} -eq 1 ]]; then
          echo "                -$opt)"
        else
          echo "                --$opt)"
        fi
        echo "                    local completions"
        echo "                    completions=\$($func 2>/dev/null)"
        echo "                    COMPREPLY=(\$(compgen -W \"\$completions\" -- \"\$cur\"))"
        echo "                    return"
        echo "                    ;;"
      done
      echo "            esac"
    fi

    # 参数位置的补全（静态值或动态函数）
    if [[ ${#arg_complete_funcs[@]} -gt 0 || ${#arg_static_values[@]} -gt 0 ]]; then
      # Build skip list: all options (app global + command-specific) that take values
      local -a val_opts_list=()
      # Add app global options with values
      if [[ ${#__radp_cli_app_global_options_spec[@]} -gt 0 ]]; then
        local _spec
        for _spec in "${__radp_cli_app_global_options_spec[@]}"; do
          local -A _oi=()
          radp_cli_parse_option_spec "$_spec" _oi
          if [[ "${_oi[has_value]}" == "true" ]]; then
            [[ -n "${_oi[short]}" ]] && val_opts_list+=("-${_oi[short]}")
            [[ -n "${_oi[long]}" ]] && val_opts_list+=("--${_oi[long]}")
          fi
        done
      fi
      # Add command-specific options with values
      local _ol
      while IFS= read -r _ol; do
        [[ -z "$_ol" ]] && continue
        local -A _oi2=()
        radp_cli_parse_option_spec "$_ol" _oi2
        if [[ "${_oi2[has_value]}" == "true" ]]; then
          [[ -n "${_oi2[short]}" ]] && val_opts_list+=("-${_oi2[short]}")
          [[ -n "${_oi2[long]}" ]] && val_opts_list+=("--${_oi2[long]}")
        fi
      done <<<"${meta[options]}"
      local val_opts_pattern
      val_opts_pattern=$(IFS='|'; echo "${val_opts_list[*]}")

      echo "            # 计算参数位置（减去命令路径深度）"
      echo "            local arg_idx=0"
      echo "            for ((i = 1; i < cword; i++)); do"
      echo "                case \"\${words[i]}\" in"
      if [[ -n "$val_opts_pattern" ]]; then
        echo "                    $val_opts_pattern)"
        echo "                        ((i++)) ;;"
      fi
      echo "                    -*) ;;"
      echo "                    *) ((arg_idx++)) ;;"
      echo "                esac"
      echo "            done"
      echo "            ((arg_idx -= $cmd_depth)) || true"
      echo "            # 根据参数位置补全"
      echo "            case \"\$arg_idx\" in"
      # Generate cases for static values
      for idx in "${!arg_static_values[@]}"; do
        local values="${arg_static_values[$idx]}"
        echo "                $idx)"
        echo "                    COMPREPLY=(\$(compgen -W \"$values\" -- \"\$cur\"))"
        echo "                    return"
        echo "                    ;;"
      done
      # Generate cases for dynamic functions
      for idx in "${!arg_complete_funcs[@]}"; do
        local func="${arg_complete_funcs[$idx]}"
        echo "                $idx)"
        echo "                    local completions"
        echo "                    completions=\$($func 2>/dev/null)"
        echo "                    COMPREPLY=(\$(compgen -W \"\$completions\" -- \"\$cur\"))"
        echo "                    return"
        echo "                    ;;"
      done
      echo "            esac"
    fi

    echo "            COMPREPLY=(\$(compgen -W \"$options\" -- \"\$cur\"))"
  else
    # 无动态补全：简单的选项补全
    echo "            COMPREPLY=(\$(compgen -W \"$options\" -- \"\$cur\"))"
  fi

  echo "            ;;"
}

#######################################
# 生成 Zsh 动态补全的 wrapper 函数
# 遍历所有命令，为每个动态补全生成一个 wrapper 函数
# Arguments:
#   1 - app_func: 应用函数名前缀
#######################################
__radp_cli_zsh_gen_completion_wrappers() {
  local app_func="$1"

  # 递归遍历所有命令
  __radp_cli_zsh_gen_wrappers_for_path "" "$app_func"
}

#######################################
# 递归生成指定路径下的 wrapper 函数
#######################################
__radp_cli_zsh_gen_wrappers_for_path() {
  local parent_path="$1"
  local app_func="$2"
  local cmd_list

  if [[ -z "$parent_path" ]]; then
    cmd_list=$(radp_cli_list_commands)
  else
    cmd_list=$(radp_cli_list_subcommands "$parent_path")
  fi

  local cmd
  for cmd in $cmd_list; do
    local full_path
    if [[ -z "$parent_path" ]]; then
      full_path="$cmd"
    else
      full_path="$parent_path $cmd"
    fi

    if radp_cli_has_subcommands "$full_path"; then
      # 递归处理子命令
      __radp_cli_zsh_gen_wrappers_for_path "$full_path" "$app_func"
    elif radp_cli_cmd_exists "$full_path"; then
      # 为该命令生成 wrapper 函数
      __radp_cli_zsh_gen_cmd_wrappers "$full_path" "$app_func"
    fi
  done
}

#######################################
# 为单个命令生成动态补全的 wrapper 函数
#######################################
__radp_cli_zsh_gen_cmd_wrappers() {
  local cmd_path="$1"
  local app_func="$2"

  local -A meta=()
  if ! radp_cli_get_cmd_meta "$cmd_path" meta 2>/dev/null; then
    return
  fi

  # 跳过没有选项和参数补全的透传模式
  if [[ "${meta[metas]}" == *passthrough* && -z "${meta[options]}" && -z "${meta[args]}" ]]; then
    return
  fi

  # 将命令路径转换为函数名后缀 (setup info -> setup_info)
  local func_suffix="${cmd_path// /_}"

  # 为参数生成 wrapper
  local arg_line arg_idx=1
  while IFS= read -r arg_line; do
    [[ -z "$arg_line" ]] && continue
    local -A arg_info=()
    radp_cli_parse_arg_spec "$arg_line" arg_info

    local complete_func
    if complete_func=$(radp_cli_get_complete_func "${arg_info[name]}" "${meta[completes]}" 2>/dev/null); then
      local wrapper_name="_${app_func}_arg_${func_suffix}_${arg_info[name]}"
      cat <<WRAPPER
${wrapper_name}() {
    local completions=(\$($complete_func 2>/dev/null))
    _describe '${arg_info[name]}' completions
}

WRAPPER
    fi
    ((arg_idx++)) || true
  done <<<"${meta[args]}"

  # 为选项值生成 wrapper
  local opt_line
  while IFS= read -r opt_line; do
    [[ -z "$opt_line" ]] && continue
    local -A opt_info=()
    radp_cli_parse_option_spec "$opt_line" opt_info

    if [[ "${opt_info[has_value]}" == "true" && -n "${opt_info[long]}" ]]; then
      local complete_func
      if complete_func=$(radp_cli_get_complete_func "${opt_info[long]}" "${meta[completes]}" 2>/dev/null); then
        local opt_name="${opt_info[long]//-/_}"
        local wrapper_name="_${app_func}_opt_${func_suffix}_${opt_name}"
        cat <<WRAPPER
${wrapper_name}() {
    local completions=(\$($complete_func 2>/dev/null))
    _describe '${opt_info[value_name]}' completions
}

WRAPPER
      fi
    fi
  done <<<"${meta[options]}"
}

#######################################
# 生成 Zsh 补全脚本
# Outputs:
#   完整的 Zsh 补全脚本
#######################################
radp_cli_completion_zsh() {
  local app_name="${__radp_cli_app_name:-cli}"
  local app_func="${app_name//-/_}"

  # 输出 #compdef 头部
  echo "#compdef $app_name"
  echo ""
  echo "# Zsh completion script for $app_name"
  echo "# Generated by radp-bash-framework"
  echo ""

  # 生成所有动态补全的 wrapper 函数
  __radp_cli_zsh_gen_completion_wrappers "$app_func"

  # 生成全局选项的 _arguments 规格（用于顶级函数）
  # 使用 brace expansion 格式（zsh 标准格式），配合 -s 标志支持短选项补全
  local global_opts_spec=""
  if [[ -n "${__radp_cli_global_options:-}" ]]; then
    local opt
    for opt in ${__radp_cli_global_options}; do
      case "$opt" in
      -q)
        global_opts_spec+="        '(-q --quiet)'{-q,--quiet}'[Enable quiet mode]' \\"$'\n'
        ;;
      --quiet)
        # 已在 -q 处理
        ;;
      -v)
        global_opts_spec+="        '(-v --verbose)'{-v,--verbose}'[Enable verbose output]' \\"$'\n'
        ;;
      --verbose)
        # 已在 -v 处理
        ;;
      --debug)
        global_opts_spec+="        '--debug[Enable debug output]' \\"$'\n'
        ;;
      --show-config)
        global_opts_spec+="        '--show-config[Show configuration]' \\"$'\n'
        ;;
      --all)
        global_opts_spec+="        '--all[Show all (with --show-config)]' \\"$'\n'
        ;;
      --json)
        global_opts_spec+="        '--json[Output as JSON (with --show-config)]' \\"$'\n'
        ;;
      *)
        # 其他选项 - 添加基本格式
        global_opts_spec+="        '${opt}[${opt}]' \\"$'\n'
        ;;
      esac
    done
  fi

  # 生成应用级全局选项的 _arguments 规格
  # 使用 brace expansion 格式（zsh 标准格式）
  local app_global_opts_spec=""
  if [[ ${#__radp_cli_app_global_options_spec[@]} -gt 0 ]]; then
    local spec
    for spec in "${__radp_cli_app_global_options_spec[@]}"; do
      local -A opt_info=()
      radp_cli_parse_option_spec "$spec" opt_info
      local opt_spec=""
      if [[ -n "${opt_info[short]}" && -n "${opt_info[long]}" ]]; then
        opt_spec="'(-${opt_info[short]} --${opt_info[long]})'{-${opt_info[short]},--${opt_info[long]}}'"
      elif [[ -n "${opt_info[long]}" ]]; then
        opt_spec="'--${opt_info[long]}'"
      fi
      if [[ -n "$opt_spec" ]]; then
        local desc="${opt_info[desc]//\'/\'\\\'\'}"
        if [[ "${opt_info[has_value]}" == "true" ]]; then
          # Add default completion function based on value_name
          local value_completion=""
          case "${opt_info[value_name]}" in
            dir)
              value_completion="_files -/"
              ;;
            file)
              value_completion="_files"
              ;;
          esac
          app_global_opts_spec+="        ${opt_spec}[${desc}]:${opt_info[value_name]}:${value_completion}' \\"$'\n'
        else
          app_global_opts_spec+="        ${opt_spec}[${desc}]' \\"$'\n'
        fi
      fi
    done
  fi

  # 递归生成所有子命令的独立函数
  local cmd
  for cmd in $(radp_cli_list_commands); do
    __radp_cli_zsh_gen_cmd_func "$app_func" "$cmd"
  done

  # 生成顶级入口函数
  # 注意：必须同时使用 -C（支持子命令状态机）和 -s（支持短选项补全）
  cat <<ZSH_COMPLETION_HEADER
_${app_func}() {
    local context state state_descr line
    typeset -A opt_args

    # Workaround: Handle option prefix completion explicitly
    # Without this, -<TAB> may fall through to command completion
    # because _arguments -C doesn't trigger option completion for
    # incomplete option prefixes when positional args are specified
    if [[ \$CURRENT -eq 2 && "\${words[CURRENT]}" == -* ]]; then
        _arguments -s \\
            '(-h --help)'{-h,--help}'[Show help]' \\
            '--version[Show version]' \\
ZSH_COMPLETION_HEADER

  # Insert global options (framework-level) for workaround block
  if [[ -n "$global_opts_spec" ]]; then
    printf '%s' "$global_opts_spec"
  fi
  # Insert global options (app-level) for workaround block
  if [[ -n "$app_global_opts_spec" ]]; then
    printf '%s' "$app_global_opts_spec"
  fi

  # Close workaround block, remove trailing backslash from last option
  cat <<'ZSH_WORKAROUND_END'
        && return
    fi

ZSH_WORKAROUND_END

  # Now output the normal _arguments -C -s block
  cat <<ZSH_COMPLETION_MAIN
    _arguments -C -s \\
        '(-h --help)'{-h,--help}'[Show help]' \\
        '--version[Show version]' \\
ZSH_COMPLETION_MAIN

  # 输出全局选项
  if [[ -n "$global_opts_spec" ]]; then
    printf '%s' "$global_opts_spec"
  fi

  # 输出应用级全局选项
  if [[ -n "$app_global_opts_spec" ]]; then
    printf '%s' "$app_global_opts_spec"
  fi

  cat <<'ZSH_COMPLETION_ARGS'
        '1: :->command' \
        '*:: :->args'

    case "$state" in
        command)
            local commands=(
ZSH_COMPLETION_ARGS

  # 生成顶级命令列表
  for cmd in $(radp_cli_list_commands); do
    local desc=""
    local -A meta=()
    if radp_cli_cmd_exists "$cmd"; then
      radp_cli_get_cmd_meta "$cmd" meta 2>/dev/null || true
      desc="${meta[desc]:-}"
    elif radp_cli_has_subcommands "$cmd"; then
      desc="Manage $cmd"
    fi
    # 转义单引号
    desc="${desc//\'/\'\\\'\'}"
    echo "                '$cmd:$desc'"
  done

  cat <<ZSH_COMPLETION_DISPATCH
            )
            _describe 'command' commands
            ;;
        args)
ZSH_COMPLETION_DISPATCH

  # Export app global options from opt_args to global variables
  # This is needed because when _arguments -C processes options and enters 'args' state,
  # the words array gets renumbered. Subcommand functions like _radp_vf_list need access
  # to the app global options (like -c/--config) but can't find them in the renumbered words.
  # Solution: export opt_args values as global variables that helper functions can check.
  if [[ ${#__radp_cli_app_global_options_spec[@]} -gt 0 ]]; then
    local spec
    for spec in "${__radp_cli_app_global_options_spec[@]}"; do
      local -A opt_info=()
      radp_cli_parse_option_spec "$spec" opt_info
      local var_name="${opt_info[long]//-/_}"
      # Use uppercase with app prefix for global variable name
      local global_var="_${app_func^^}_OPT_${var_name^^}"
      if [[ -n "${opt_info[short]}" ]]; then
        echo "            typeset -g ${global_var}=\"\${opt_args[-${opt_info[short]}]:-\${opt_args[--${opt_info[long]}]:-}}\""
      elif [[ -n "${opt_info[long]}" ]]; then
        echo "            typeset -g ${global_var}=\"\${opt_args[--${opt_info[long]}]:-}\""
      fi
    done
  fi

  cat <<ZSH_COMPLETION_DISPATCH2
            local cmd_func="_${app_func}_\${words[1]//-/_}"
            if (( \$+functions[\$cmd_func] )); then
                \$cmd_func
            else
                _files
            fi
            ;;
    esac
}
ZSH_COMPLETION_DISPATCH2

  echo
  echo "_${app_func} \"\$@\""
}

#######################################
# 递归生成 Zsh 命令函数（新的函数式方法）
# 为每个命令生成独立的函数，使用 _arguments -C 自动处理 word 移位
# Arguments:
#   1 - app_func: 应用函数名前缀
#   2 - cmd_path: 当前命令路径
#######################################
__radp_cli_zsh_gen_cmd_func() {
  local app_func="$1"
  local cmd_path="$2"
  local func_name="_${app_func}_${cmd_path// /_}"
  func_name="${func_name//-/_}"

  if radp_cli_has_subcommands "$cmd_path"; then
    # 有子命令：生成带状态机的函数
    # 注意：必须同时使用 -C（支持子命令状态机）和 -s（支持短选项补全）
    cat <<FUNC_HEADER
${func_name}() {
    local context state state_descr line
    typeset -A opt_args

    _arguments -C -s \\
        '(-h --help)'{-h,--help}'[Show help]' \\
        '1: :->command' \\
        '*:: :->args'

    case "\$state" in
        command)
            local commands=(
FUNC_HEADER

    local subcmd
    for subcmd in $(radp_cli_list_subcommands "$cmd_path"); do
      local desc=""
      local -A sub_meta=()
      local full_path="$cmd_path $subcmd"
      if radp_cli_cmd_exists "$full_path"; then
        radp_cli_get_cmd_meta "$full_path" sub_meta 2>/dev/null || true
        desc="${sub_meta[desc]:-}"
      elif radp_cli_has_subcommands "$full_path"; then
        desc="Manage $subcmd"
      fi
      desc="${desc//\'/\'\\\'\'}"
      echo "                '$subcmd:$desc'"
    done

    cat <<FUNC_DISPATCH
            )
            _describe 'subcommand' commands
            ;;
        args)
            local cmd_func="${func_name}_\${words[1]//-/_}"
            if (( \$+functions[\$cmd_func] )); then
                \$cmd_func
            else
                _files
            fi
            ;;
    esac
}

FUNC_DISPATCH

    # 递归生成子命令的函数
    for subcmd in $(radp_cli_list_subcommands "$cmd_path"); do
      __radp_cli_zsh_gen_cmd_func "$app_func" "$cmd_path $subcmd"
    done
  else
    # 没有子命令：生成叶子命令函数（直接补全选项和参数）
    __radp_cli_zsh_gen_leaf_func "$app_func" "$cmd_path" "$func_name"
  fi
}

#######################################
# 生成 Zsh 叶子命令函数（没有子命令的命令）
# Arguments:
#   1 - app_func: 应用函数名前缀
#   2 - cmd_path: 命令路径
#   3 - func_name: 函数名
#######################################
__radp_cli_zsh_gen_leaf_func() {
  local app_func="$1"
  local cmd_path="$2"
  local func_name="$3"

  echo "${func_name}() {"

  if ! radp_cli_cmd_exists "$cmd_path"; then
    echo "    _arguments -s '(-h --help)'{-h,--help}'[Show help]' '*:file:_files'"
    echo "}"
    echo ""
    return
  fi

  local -A meta=()
  if ! radp_cli_get_cmd_meta "$cmd_path" meta 2>/dev/null; then
    echo "    _arguments -s '(-h --help)'{-h,--help}'[Show help]' '*:file:_files'"
    echo "}"
    echo ""
    return
  fi

  # passthrough 模式：如果没有定义选项，只使用通用文件补全
  if [[ "${meta[metas]}" == *passthrough* && -z "${meta[options]}" ]]; then
    echo "    _files"
    echo "}"
    echo ""
    return
  fi

  # 将命令路径转换为函数名后缀
  local func_suffix="${cmd_path// /_}"

  echo "    _arguments -s \\"
  echo "        '(-h --help)'{-h,--help}'[Show help]' \\"

  # 生成应用级全局选项（让每个命令都能补全 -c/--config 等）
  if [[ ${#__radp_cli_app_global_options_spec[@]} -gt 0 ]]; then
    local _agspec
    for _agspec in "${__radp_cli_app_global_options_spec[@]}"; do
      local -A _ag_info=()
      radp_cli_parse_option_spec "$_agspec" _ag_info
      local _ag_opt_spec=""
      if [[ -n "${_ag_info[short]}" && -n "${_ag_info[long]}" ]]; then
        _ag_opt_spec="'(-${_ag_info[short]} --${_ag_info[long]})'{-${_ag_info[short]},--${_ag_info[long]}}'"
      elif [[ -n "${_ag_info[long]}" ]]; then
        _ag_opt_spec="'--${_ag_info[long]}'"
      fi
      if [[ -n "$_ag_opt_spec" ]]; then
        local _ag_desc="${_ag_info[desc]//\'/\'\\\'\'}"
        if [[ "${_ag_info[has_value]}" == "true" ]]; then
          local _ag_value_completion=""
          case "${_ag_info[value_name]}" in
            dir) _ag_value_completion="_files -/" ;;
            file) _ag_value_completion="_files" ;;
          esac
          echo "        ${_ag_opt_spec}[${_ag_desc}]:${_ag_info[value_name]}:${_ag_value_completion}' \\"
        else
          echo "        ${_ag_opt_spec}[${_ag_desc}]' \\"
        fi
      fi
    done
  fi

  # 生成选项补全
  local opt_line
  while IFS= read -r opt_line; do
    [[ -z "$opt_line" ]] && continue
    local -A opt_info=()
    radp_cli_parse_option_spec "$opt_line" opt_info

    local opt_spec=""
    if [[ -n "${opt_info[short]}" && -n "${opt_info[long]}" ]]; then
      # Format: '(-s --long)'{-s,--long}'[desc]'
      opt_spec="'(-${opt_info[short]} --${opt_info[long]})'{-${opt_info[short]},--${opt_info[long]}}'"
    elif [[ -n "${opt_info[long]}" ]]; then
      # Format: '--long[desc]' (no exclusion group needed for long-only options)
      opt_spec="'--${opt_info[long]}"
    fi

    if [[ -n "$opt_spec" ]]; then
      local desc="${opt_info[desc]//\'/\'\\\'\'}"
      if [[ "${opt_info[has_value]}" == "true" ]]; then
        local complete_func
        if complete_func=$(radp_cli_get_complete_func "${opt_info[long]}" "${meta[completes]}" 2>/dev/null); then
          local opt_name="${opt_info[long]//-/_}"
          local wrapper_name="_${app_func}_opt_${func_suffix}_${opt_name}"
          echo "        ${opt_spec}[${desc}]:${opt_info[value_name]}:${wrapper_name}' \\"
        else
          echo "        ${opt_spec}[${desc}]:${opt_info[value_name]}:' \\"
        fi
      else
        echo "        ${opt_spec}[${desc}]' \\"
      fi
    fi
  done <<<"${meta[options]}"

  # 收集参数补全规格
  local -a arg_specs=()
  local arg_line arg_idx=1
  while IFS= read -r arg_line; do
    [[ -z "$arg_line" ]] && continue
    local -A arg_info=()
    radp_cli_parse_arg_spec "$arg_line" arg_info

    local arg_spec=""
    if [[ "${arg_info[variadic]}" == "true" ]]; then
      arg_spec="'*"
    else
      arg_spec="'$arg_idx"
    fi

    # Check for static values first (via @arg-values)
    local static_values
    if static_values=$(radp_cli_get_arg_values "${arg_info[name]}" "${meta[arg_values]}" 2>/dev/null); then
      # Use static completion: '1:name:(val1 val2 val3)'
      arg_specs+=("${arg_spec}:${arg_info[name]}:(${static_values})'")
    else
      # Check for dynamic completion function
      local complete_func
      if complete_func=$(radp_cli_get_complete_func "${arg_info[name]}" "${meta[completes]}" 2>/dev/null); then
        local wrapper_name="_${app_func}_arg_${func_suffix}_${arg_info[name]}"
        arg_specs+=("${arg_spec}:${arg_info[name]}:${wrapper_name}'")
      else
        arg_specs+=("${arg_spec}:${arg_info[name]}:_files'")
      fi
    fi
    ((arg_idx++)) || true
  done <<<"${meta[args]}"

  # 如果没有参数，添加默认文件补全
  if [[ ${#arg_specs[@]} -eq 0 ]]; then
    arg_specs+=("'*:file:_files'")
  fi

  # 输出参数补全（最后一个不加 \）
  local i
  for ((i = 0; i < ${#arg_specs[@]}; i++)); do
    if [[ $i -lt $((${#arg_specs[@]} - 1)) ]]; then
      echo "        ${arg_specs[$i]} \\"
    else
      echo "        ${arg_specs[$i]}"
    fi
  done

  echo "}"
  echo ""
}

#######################################
#######################################
# 生成补全脚本（统一入口）
# Arguments:
#   1 - shell: shell 类型（bash 或 zsh）
# Outputs:
#   补全脚本
# Returns:
#   0 - 成功
#   1 - 不支持的 shell 类型
#######################################
radp_cli_completion_generate() {
  local shell="$1"

  case "$shell" in
  bash)
    radp_cli_completion_bash
    ;;
  zsh)
    radp_cli_completion_zsh
    ;;
  *)
    radp_log_error "Unsupported shell: $shell (supported: bash, zsh)"
    return 1
    ;;
  esac
}
