###-begin-{pkgname}-completion-###
#
# Bash completion for {pkgname}
# Strategy: Cache-first with selective CLI fallback for resource names
#
if type complete &>/dev/null; then
  # Cache file location
  _{pkgname}_cache_file="$HOME/.config/cpln/completion-cache"

  # Commands that require dynamic resource name completion
  _{pkgname}_resource_commands="get|edit|delete|patch|clone|update|tag|permissions|access-report|eventlog|open|connect|exec|force-redeployment|start|stop|run|get-replicas|get-deployments"

  # ============================================================================
  # Helper Functions
  # ============================================================================

  # Get completions from cache file
  # Args: $1=cache_key, $2=current_word, $3=filter_type (opts|cmds|empty)
  _{pkgname}_get_cached() {
    local key="$1"
    local cur="$2"
    local filter_opts="${3:-}"

    [[ ! -f "$_{pkgname}_cache_file" ]] && return 1

    # Find the matching cache line
    local line=$(grep "^${key}:" "$_{pkgname}_cache_file" 2>/dev/null)
    [[ -z "$line" ]] && return 1

    # Extract completions after the colon
    local completions="${line#*:}"

    # Filter and match completions
    local IFS=','
    local filtered=()
    for item in $completions; do
      # Apply filter: opts (--options only), cmds (commands only)
      if [[ "$filter_opts" == "opts" && "$item" != --* ]]; then
        continue
      fi
      if [[ "$filter_opts" == "cmds" && "$item" == --* ]]; then
        continue
      fi
      # Match prefix
      if [[ "$item" == "$cur"* ]]; then
        filtered+=("$item")
      fi
    done

    if [[ ${#filtered[@]} -gt 0 ]]; then
      COMPREPLY=("${filtered[@]}")
      return 0
    fi
    return 1
  }

  # Validate that a command path exists in cache
  # Args: $1=cmd, $2=subcmd, $3=subsubcmd
  _{pkgname}_is_valid_path() {
    local cmd="$1"
    local subcmd="$2"
    local subsubcmd="$3"

    [[ ! -f "$_{pkgname}_cache_file" ]] && return 1

    # Check top-level command
    if [[ -n "$cmd" ]]; then
      local top_cmds=$(grep "^:" "$_{pkgname}_cache_file" 2>/dev/null | cut -d: -f2)
      if [[ -z "$top_cmds" || ! ",$top_cmds," == *",$cmd,"* ]]; then
        return 1
      fi
    fi

    # Check subcommand
    if [[ -n "$subcmd" ]]; then
      local sub_line=$(grep "^${cmd}:" "$_{pkgname}_cache_file" 2>/dev/null)
      [[ -z "$sub_line" ]] && return 1
      local sub_cmds="${sub_line#*:}"
      local found=0
      local IFS=','
      for item in $sub_cmds; do
        if [[ "$item" == "$subcmd" && "$item" != --* ]]; then
          found=1
          break
        fi
      done
      [[ $found -eq 0 ]] && return 1
    fi

    # Check sub-subcommand
    if [[ -n "$subsubcmd" ]]; then
      local subsub_line=$(grep "^${cmd} ${subcmd}:" "$_{pkgname}_cache_file" 2>/dev/null)
      [[ -z "$subsub_line" ]] && return 1
      local subsub_cmds="${subsub_line#*:}"
      local found=0
      local IFS=','
      for item in $subsub_cmds; do
        if [[ "$item" == "$subsubcmd" && "$item" != --* ]]; then
          found=1
          break
        fi
      done
      [[ $found -eq 0 ]] && return 1
    fi

    return 0
  }

  # Build command context (commands only, excluding options, their values, and positional args)
  _{pkgname}_get_cmd_context() {
    local -a cmd_parts=()
    local i skip_next=0
    local cache_key=""

    for ((i=1; i<cword; i++)); do
      [[ $skip_next -eq 1 ]] && { skip_next=0; continue; }

      local w="${words[i]}"

      # Skip options and their values
      if [[ "$w" == --* ]]; then
        [[ "$w" != *=* ]] && skip_next=1
        continue
      elif [[ "$w" == -* ]]; then
        skip_next=1
        continue
      fi

      # Validate word is a known subcommand at the current level
      local cache_line=$(grep "^${cache_key}:" "$_{pkgname}_cache_file" 2>/dev/null)
      if [[ -n "$cache_line" ]]; then
        local cmds="${cache_line#*:}"
        local is_cmd=0
        local saved_IFS="$IFS"
        local IFS=','
        for item in $cmds; do
          if [[ "$item" == "$w" && "$item" != --* ]]; then
            is_cmd=1
            break
          fi
        done
        IFS="$saved_IFS"

        if [[ $is_cmd -eq 1 ]]; then
          cmd_parts+=("$w")
          cache_key="${cmd_parts[*]}"
        fi
        # else: positional argument, skip
      fi
    done

    echo "${cmd_parts[*]}"
  }

  # ============================================================================
  # Main Completion Function
  # ============================================================================

  _{pkgname}_completion() {
    local words cword cur prev

    # Get completion words using bash-completion helper if available
    if type _get_comp_words_by_ref &>/dev/null; then
      _get_comp_words_by_ref -n = -n @ -n : -w words -i cword
    else
      cword="$COMP_CWORD"
      words=("${COMP_WORDS[@]}")
    fi

    cur="${words[cword]}"
    prev="${words[cword-1]}"

    # ------------------------------------------------------------------------
    # 1. File completion (instant, no cache needed)
    # ------------------------------------------------------------------------
    case "$prev" in
      --file|-f|--cert-file|--key-file)
        compopt -o filenames 2>/dev/null
        COMPREPLY=($(compgen -f -- "$cur"))
        return 0
        ;;
    esac

    # ------------------------------------------------------------------------
    # 1b. Dynamic option value completion (profile, endpoint, org, gvc, output)
    # ------------------------------------------------------------------------
    if [[ "$prev" == --profile || "$prev" == --endpoint || "$prev" == --org || "$prev" == --gvc || "$prev" == --output || "$prev" == -o ]]; then
      local completions
      completions=$(COMP_CWORD="$cword" \
                    COMP_LINE="$COMP_LINE" \
                    COMP_POINT="$COMP_POINT" \
                    {completer} completion -- "${words[@]}" 2>/dev/null)

      local IFS=$'\n'
      local names=()
      for line in $completions; do
        [[ "$line" == "$cur"* ]] && names+=("$line")
      done

      COMPREPLY=("${names[@]}")
      return 0
    fi

    # ------------------------------------------------------------------------
    # 2. Build command context and validate
    # ------------------------------------------------------------------------
    local cmd_ctx=$(_{pkgname}_get_cmd_context)
    local -a ctx_parts=($cmd_ctx)
    local ctx_len=${#ctx_parts[@]}

    # Validate command path - reject invalid paths immediately (no CLI call)
    if [[ $ctx_len -ge 1 ]]; then
      local v_cmd="${ctx_parts[0]}"
      local v_subcmd="${ctx_parts[1]:-}"
      local v_subsubcmd="${ctx_parts[2]:-}"
      _{pkgname}_is_valid_path "$v_cmd" "$v_subcmd" "$v_subsubcmd" || return 0
    fi

    # ------------------------------------------------------------------------
    # 3. Cache-based completion (fast)
    # ------------------------------------------------------------------------

    # Option completion (when typing --)
    if [[ "$cur" == -* ]]; then
      _{pkgname}_get_cached "$cmd_ctx" "$cur" "opts" && return 0
    fi

    # Top-level commands (cpln <TAB>)
    if [[ $cword -eq 1 ]]; then
      _{pkgname}_get_cached "" "$cur" "cmds" && return 0
    fi

    # Command completion for any depth (recursive support)
    # Try commands first, then fall back to options
    if [[ $ctx_len -ge 1 && "$cur" != -* ]]; then
      # Try to get commands from current context
      _{pkgname}_get_cached "$cmd_ctx" "$cur" "cmds" && return 0
      # Fallback to options if no commands available
      _{pkgname}_get_cached "$cmd_ctx" "$cur" "opts" && return 0
    fi

    # ------------------------------------------------------------------------
    # 4. Dynamic completion (slow, only for resource names)
    # ------------------------------------------------------------------------
    # Only call CLI for commands that need resource name completion
    # Example: cpln workload get <name-TAB>
    if [[ $ctx_len -eq 2 && "$cur" != -* ]]; then
      local subcmd="${ctx_parts[1]}"

      if [[ "$subcmd" =~ ^(${_{pkgname}_resource_commands})$ ]]; then
        local completions
        completions=$(COMP_CWORD="$cword" \
                      COMP_LINE="$COMP_LINE" \
                      COMP_POINT="$COMP_POINT" \
                      {completer} completion -- "${words[@]}" 2>/dev/null)

        local IFS=$'\n'
        local names=()
        for line in $completions; do
          local name="${line%%:*}"
          [[ "$name" == "$cur"* ]] && names+=("$name")
        done

        COMPREPLY=("${names[@]}")
        [[ ${#COMPREPLY[@]} -gt 0 ]] && return 0
      fi
    fi

    # ------------------------------------------------------------------------
    # 5. File completion fallback for positional args (e.g., chart paths)
    # ------------------------------------------------------------------------
    compopt -o filenames 2>/dev/null
    COMPREPLY=($(compgen -f -- "$cur"))
  }

  # Register completion function
  # Note: -o default is intentionally omitted to prevent file completion fallback
  # File completion is handled explicitly for --file and similar options
  complete -F _{pkgname}_completion {pkgname}
fi
###-end-{pkgname}-completion-###
