#!/bin/bash

# Get script directory for commands-db.json location
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DB_FILE="$SCRIPT_DIR/commands-db.json"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m' # No Color

# ASCII Banner
show_banner() {
  echo -en "${CYAN}"
  cat <<'BANNER'
 ____                          __  __
/ ___| _   _ _ __   ___ _ __  |  \/  | __ _ _ __
\___ \| | | | '_ \ / _ \ '__| | |\/| |/ _` | '_ \
 ___) | |_| | |_) |  __/ |    | |  | | (_| | | | |
|____/ \__,_| .__/ \___|_|    |_|  |_|\__,_|_| |_|
            |_|
BANNER
  echo -e "${NC}${YELLOW}        Your Intelligent CLI Assistant for Bash${NC}"
  echo ""
}

show_help() {
  show_banner
  echo -e "${BOLD}${YELLOW}QUICK START${NC}"
  echo -e "  ${GREEN}super-man ask \"find large files\"${NC}     # Ask a question"
  echo -e "  ${GREEN}super-man category files${NC}             # Browse by category"
  echo -e "  ${GREEN}super-man explain \"tar -czf\"${NC}         # Explain a command"
  echo ""
  echo -e "${BOLD}${YELLOW}MODES${NC}"
  echo -e "  ${CYAN}Natural Language Queries:${NC}"
  echo -e "    ${GREEN}ask${NC} \"query\"           Ask in natural language (database)"
  echo -e "    ${GREEN}task${NC} \"description\"    Describe what you want to do (database)"
  echo -e "    ${GREEN}ai${NC} \"complex query\"    AI bash one-liner via local LLM (advanced) 🤖"
  echo ""
  echo -e "  ${CYAN}Browse & Explore:${NC}"
  echo -e "    ${GREEN}category${NC} NAME          Browse by category (files/text/network/system)"
  echo -e "    ${GREEN}explain${NC} \"command\"      Explain what a command does"
  echo ""
  echo -e "  ${CYAN}Direct Lookup:${NC}"
  echo -e "    ${GREEN}COMMAND [FILTER]${NC}       Show flags for command (e.g., ls size)"
  echo -e "    ${GREEN}-i${NC}, ${GREEN}--interactive${NC}      Interactive fzf mode"
  echo -e "    ${GREEN}-l${NC}, ${GREEN}--list${NC}             List all commands"
  echo ""
  echo -e "${BOLD}${YELLOW}CATEGORIES${NC} (20+ tasks)"
  echo -e "  ${CYAN}files${NC}    File operations (compress, find, permissions, symlinks)"
  echo -e "  ${CYAN}text${NC}     Text processing (search, replace, compare, count)"
  echo -e "  ${CYAN}network${NC}  Network ops (download, ports, ping)"
  echo -e "  ${CYAN}system${NC}   System monitoring (cpu, memory, processes)"
  echo ""
  echo -e "${BOLD}${YELLOW}EXAMPLES${NC}"
  echo -e "  ${DIM}# Natural language${NC}"
  echo "  super-man ask \"compress folder\""
  echo "  super-man ask \"search text in files\""
  echo "  super-man task \"monitor cpu usage\""
  echo ""
  echo -e "  ${DIM}# Browse and learn${NC}"
  echo "  super-man category network"
  echo "  super-man explain \"find . -name '*.txt'\""
  echo ""
  echo -e "  ${DIM}# Original modes (still work)${NC}"
  echo "  super-man ls size          # Direct flag lookup"
  echo "  super-man                  # Interactive fzf mode"
  echo ""
  echo -e "${BOLD}${YELLOW}REQUIREMENTS${NC}"
  echo -e "  ${GREEN}✓${NC} jq (for natural language queries)"
  echo -e "  ${GREEN}✓${NC} fzf (for interactive mode only)"
  echo ""
  echo -e "${BOLD}${YELLOW}AI MODE${NC} 🤖"
  echo -e "  Generate bash one-liners from plain English via a local ollama model:"
  echo -e "    ${GREEN}super-man ai \"find python files modified last week\"${NC}"
  echo -e "    ${GREEN}super-man ai --model qwen2.5:3b \"count lines in all js files\"${NC}"
  echo -e "    ${GREEN}super-man ai --compare \"list the 5 largest files\"${NC}   # A/B models"
  echo ""
  echo -e "  Default model: ${CYAN}${SUPERMAN_AI_MODEL}${NC}"
  echo "  Configure via env vars:"
  echo "    SUPERMAN_AI_MODEL           default model (e.g. westenfelder/NL2SH)"
  echo "    SUPERMAN_AI_COMPARE_MODELS  space-separated list for --compare"
  echo ""
  echo -e "${YELLOW}Database:${NC} $DB_FILE"
  echo -e "${YELLOW}Version:${NC} 2.2.0 (250+ commands, configurable local AI)"
  echo ""
}

# Check if jq is available
check_jq() {
  if ! command -v jq &> /dev/null; then
    echo -e "${RED}Error: jq is not installed${NC}"
    echo "jq is required for database search features."
    echo "Install it with: sudo apt install jq"
    echo ""
    echo "You can still use the original modes:"
    echo "  super-man COMMAND [FILTER]"
    echo "  super-man --interactive"
    return 1
  fi
  return 0
}

# Check if database exists
check_database() {
  if [ ! -f "$DB_FILE" ]; then
    echo -e "${RED}Error: Database file not found${NC}"
    echo "Expected location: $DB_FILE"
    echo ""
    echo "You can still use the original modes for direct command lookup."
    return 1
  fi
  return 0
}

# Search database by keywords
search_by_keywords() {
  local query="$1"
  local max_results="${2:-3}"

  if ! check_jq || ! check_database; then
    return 1
  fi

  # Convert query to lowercase for matching
  local query_lower=$(echo "$query" | tr '[:upper:]' '[:lower:]')

  # Search and score tasks based on keyword matches
  jq -r --arg query "$query_lower" --argjson max "$max_results" '
    .tasks[] |
    # Calculate score based on keyword matches
    . as $task |
    ($query | split(" ") | map(select(length > 2))) as $query_words |
    (
      [
        $query_words[] as $word |
        (
          (.keywords | map(select(. | ascii_downcase | contains($word))) | length) * 2 +
          (if (.description | ascii_downcase | contains($word)) then 1 else 0 end) +
          (if (.command | ascii_downcase | contains($word)) then 1 else 0 end)
        )
      ] | add // 0
    ) as $score |
    select($score > 0) |
    {score: $score, task: .}
  ' "$DB_FILE" | jq -s --argjson max "$max_results" 'sort_by(-.score) | .[0:$max] | .[] | .task'
}

# Display a task with full details
show_task() {
  local task_json="$1"

  local id=$(echo "$task_json" | jq -r '.id')
  local desc=$(echo "$task_json" | jq -r '.description')
  local cmd=$(echo "$task_json" | jq -r '.command')
  local category=$(echo "$task_json" | jq -r '.category')

  echo ""
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo -e "${GREEN}Task:${NC} $desc"
  echo -e "${CYAN}Category:${NC} $category"
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo ""
  echo -e "${YELLOW}Command:${NC}"
  echo -e "  ${MAGENTA}$cmd${NC}"
  echo ""

  # Show flags explanation if available
  local flags=$(echo "$task_json" | jq -r '.flags_explained // empty')
  if [ -n "$flags" ]; then
    echo -e "${YELLOW}Flags explained:${NC}"
    echo "$task_json" | jq -r '.flags_explained | to_entries[] | "  \(.key) : \(.value)"'
    echo ""
  fi

  # Show examples
  local examples=$(echo "$task_json" | jq -r '.examples // empty')
  if [ -n "$examples" ]; then
    echo -e "${YELLOW}Examples:${NC}"
    echo "$task_json" | jq -r '.examples[] | "  \(.desc)\n    → \(.cmd)\n"'
  fi

  # Show related tasks
  local related=$(echo "$task_json" | jq -r '.related // empty')
  if [ -n "$related" ] && [ "$related" != "null" ]; then
    echo -e "${YELLOW}Related tasks:${NC}"
    echo "$task_json" | jq -r '.related[]' | while read -r rel_id; do
      local rel_desc=$(jq -r --arg id "$rel_id" '.tasks[] | select(.id == $id) | .description' "$DB_FILE")
      if [ -n "$rel_desc" ] && [ "$rel_desc" != "null" ]; then
        echo "  • $rel_desc (id: $rel_id)"
      fi
    done
    echo ""
  fi

  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
}

# Show compact task result (for multiple results)
show_task_compact() {
  local task_json="$1"
  local number="$2"

  local desc=$(echo "$task_json" | jq -r '.description')
  local cmd=$(echo "$task_json" | jq -r '.command')

  echo -e "${CYAN}${number}.${NC} ${GREEN}$desc${NC}"
  echo -e "   ${MAGENTA}$cmd${NC}"
  echo ""
}

# Ask mode - search database and show results
mode_ask() {
  local query="$1"

  if [ -z "$query" ]; then
    echo -e "${RED}Error: No query provided${NC}"
    echo "Usage: super-man ask \"your question\""
    return 1
  fi

  echo -e "${CYAN}Searching for:${NC} \"$query\""

  # Search database
  local results=$(search_by_keywords "$query" 5)

  if [ -z "$results" ]; then
    echo ""
    echo -e "${YELLOW}No matches found for: \"$query\"${NC}"
    echo ""
    echo "Try:"
    echo "  • Using different keywords"
    echo "  • Browse by category: super-man category files"
    echo "  • List all commands: super-man --list"
    return 1
  fi

  # Count results
  local count=$(echo "$results" | jq -s 'length')

  if [ "$count" -eq 1 ]; then
    # Single result - show full details
    show_task "$results"
  else
    # Multiple results - show compact list
    echo ""
    echo -e "${GREEN}Found $count matches:${NC}"
    echo ""

    local i=1
    echo "$results" | jq -c '.' | while read -r task; do
      show_task_compact "$task" "$i"
      i=$((i+1))
    done

    echo -e "${YELLOW}Tip:${NC} Use more specific keywords to narrow results"
  fi
}

# Category mode - browse tasks by category
mode_category() {
  local cat_name="$1"

  if ! check_jq || ! check_database; then
    return 1
  fi

  if [ -z "$cat_name" ]; then
    echo -e "${YELLOW}Available categories:${NC}"
    echo ""
    jq -r '.categories | to_entries[] | "  \(.key) : \(.value.name)"' "$DB_FILE"
    echo ""
    echo "Usage: super-man category NAME"
    return 1
  fi

  # Get category info
  local cat_data=$(jq --arg cat "$cat_name" '.categories[$cat]' "$DB_FILE")

  if [ "$cat_data" = "null" ]; then
    echo -e "${RED}Category not found:${NC} $cat_name"
    echo ""
    echo "Available categories:"
    jq -r '.categories | keys[]' "$DB_FILE" | sed 's/^/  /'
    return 1
  fi

  local cat_title=$(echo "$cat_data" | jq -r '.name')
  local task_ids=$(echo "$cat_data" | jq -r '.tasks[]')

  echo ""
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo -e "${CYAN}Category:${NC} ${GREEN}$cat_title${NC}"
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo ""

  local i=1
  for task_id in $task_ids; do
    local task=$(jq --arg id "$task_id" '.tasks[] | select(.id == $id)' "$DB_FILE")
    if [ -n "$task" ] && [ "$task" != "null" ]; then
      show_task_compact "$task" "$i"
      i=$((i+1))
    fi
  done
}

# AI mode - use NL2SH model for complex queries
# Generate bash one-liners from natural language via a local ollama model.
# The model is configurable so we can A/B different local LLMs:
#   SUPERMAN_AI_MODEL          default model (default: qwen2.5-coder:1.5b)
#   SUPERMAN_AI_COMPARE_MODELS space-separated list used by `ai --compare`
# Override per call with `--model NAME`; run every comparison model side by
# side with `--compare`. NL2SH is purpose-built for NL->shell so it receives
# the raw query; general coder models get an instruction wrapper plus markdown
# fence stripping so they too emit a single bare command.
SUPERMAN_AI_MODEL="${SUPERMAN_AI_MODEL:-qwen2.5-coder:1.5b}"
SUPERMAN_AI_COMPARE_MODELS="${SUPERMAN_AI_COMPARE_MODELS:-qwen2.5-coder:1.5b westenfelder/NL2SH}"

# Build a model-appropriate prompt for a query.
ai_build_prompt() {
  local model="$1" query="$2"
  case "$model" in
    *NL2SH*|*nl2sh*)
      printf '%s' "$query"
      ;;
    *)
      printf 'You are a bash expert. Output ONLY a single bash one-liner that accomplishes the task. No explanation, no comments, no markdown code fences. Task: %s' "$query"
      ;;
  esac
}

# Strip markdown fences and surrounding blank lines from a raw model response.
ai_clean_response() {
  awk '/^[[:space:]]*```/ { next } { print }' \
    | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' \
    | sed '/^$/d'
}

# True if an ollama model is pulled locally.
ai_model_installed() {
  ollama list 2>/dev/null | grep -q "$1"
}

# Generate a cleaned command from one model for a query.
ai_generate() {
  local model="$1" query="$2"
  ollama run "$model" "$(ai_build_prompt "$model" "$query")" 2>/dev/null | ai_clean_response
}

# Print the man/help NAME line for the base command of a generated one-liner.
ai_explain_base() {
  local base_cmd
  base_cmd=$(echo "$1" | awk '{print $1}')
  if type "$base_cmd" 2>/dev/null | grep -q "shell builtin"; then
    echo -e "${YELLOW}Command Info:${NC}"
    help "$base_cmd" 2>/dev/null | head -3
    echo ""
  elif command -v "$base_cmd" &> /dev/null; then
    echo -e "${YELLOW}Command Info:${NC}"
    man "$base_cmd" 2>/dev/null | col -b | grep -A 2 "^NAME" | tail -2
    echo ""
  fi
}

mode_ai() {
  local compare=false
  local model="$SUPERMAN_AI_MODEL"
  local args=()
  while [ $# -gt 0 ]; do
    case "$1" in
      --compare|-c) compare=true ;;
      --model|-m) shift; model="$1" ;;
      *) args+=("$1") ;;
    esac
    shift
  done
  local user_query="${args[*]}"

  if [ -z "$user_query" ]; then
    echo -e "${RED}Error: No query provided${NC}"
    echo "Usage: super-man ai [--model NAME|--compare] \"your query\""
    echo ""
    echo "Examples:"
    echo "  super-man ai \"find all python files modified in last week\""
    echo "  super-man ai --model qwen2.5:3b \"count lines in all js files\""
    echo "  super-man ai --compare \"list the 5 largest files\""
    return 1
  fi

  # Check if ollama is available
  if ! command -v ollama &> /dev/null; then
    echo -e "${RED}Error: Ollama is not installed${NC}"
    echo ""
    echo "Install Ollama:"
    echo "  curl -fsSL https://ollama.com/install.sh | sh"
    echo ""
    echo "For now, try: super-man ask \"$user_query\""
    return 1
  fi

  # ── Compare mode: run every configured model side by side ──────────────────
  if $compare; then
    echo ""
    echo -e "${CYAN}🤖 AI Compare${NC}"
    echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
    echo -e "${YELLOW}Query:${NC} $user_query"
    echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
    local m
    for m in $SUPERMAN_AI_COMPARE_MODELS; do
      echo ""
      echo -e "${BOLD}${MAGENTA}▸ $m${NC}"
      if ! ai_model_installed "$m"; then
        echo -e "  ${DIM}not installed — pull with: ollama pull $m${NC}"
        continue
      fi
      local start end elapsed out
      start=$(date +%s.%N)
      out=$(ai_generate "$m" "$user_query")
      end=$(date +%s.%N)
      elapsed=$(awk "BEGIN{printf \"%.1f\", $end-$start}")
      if [ -z "$out" ]; then
        echo -e "  ${RED}(no response)${NC}  ${DIM}(${elapsed}s)${NC}"
      else
        echo -e "  ${GREEN}$out${NC}  ${DIM}(${elapsed}s)${NC}"
      fi
    done
    echo ""
    echo -e "${DIM}Note: Always review AI-generated commands before running them!${NC}"
    echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
    return 0
  fi

  # ── Single-model mode ──────────────────────────────────────────────────────
  if ! ai_model_installed "$model"; then
    echo -e "${YELLOW}Model '$model' not found. Installed models:${NC}"
    ollama list
    echo ""
    echo "Pull it with:    ollama pull $model"
    echo "Or pick another: super-man ai --model NAME \"$user_query\""
    return 1
  fi

  echo ""
  echo -e "${CYAN}🤖 AI Assistant — $model${NC}"
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo -e "${YELLOW}Query:${NC} $user_query"
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo ""
  echo -e "${DIM}Generating bash command...${NC}"
  echo ""

  local response=$(ai_generate "$model" "$user_query")

  if [ -z "$response" ]; then
    echo -e "${RED}Error: No response from AI model${NC}"
    echo ""
    echo "Try a simpler query or use: super-man ask \"$user_query\""
    return 1
  fi

  # Display the generated command
  echo -e "${GREEN}Generated Command:${NC}"
  echo -e "  ${MAGENTA}$response${NC}"
  echo ""

  ai_explain_base "$response"

  echo -e "${DIM}Note: Always review AI-generated commands before running them!${NC}"
  echo ""
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
}

# Explain mode - parse and explain a command
mode_explain() {
  local cmd_line="$1"

  if [ -z "$cmd_line" ]; then
    echo -e "${RED}Error: No command provided${NC}"
    echo "Usage: super-man explain \"command with flags\""
    echo ""
    echo "Example:"
    echo "  super-man explain \"tar -czf archive.tar.gz folder/\""
    return 1
  fi

  # Extract the base command
  local base_cmd=$(echo "$cmd_line" | awk '{print $1}')

  echo ""
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo -e "${YELLOW}Command:${NC} ${MAGENTA}$cmd_line${NC}"
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo ""

  # Get syntax from man page SYNOPSIS section
  if command -v "$base_cmd" &> /dev/null || type "$base_cmd" 2>/dev/null | grep -q "shell builtin"; then
    echo -e "${CYAN}${BOLD}SYNTAX:${NC}"

    local raw_syntax=""
    if type "$base_cmd" 2>/dev/null | grep -q "shell builtin"; then
      # For builtins, get the first line of help
      raw_syntax=$(help "$base_cmd" 2>/dev/null | head -1 | sed 's/^[[:space:]]*//')
      [ -z "$raw_syntax" ] && raw_syntax="$base_cmd [options]"
    else
      # For regular commands, extract SYNOPSIS section from man page
      local synopsis=$(man "$base_cmd" 2>/dev/null | col -b | sed -n '/^SYNOPSIS/,/^DESCRIPTION/p' | head -15 | tail -n +2 | head -n -1 | tr '\n' ' ' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
      if [ -n "$synopsis" ]; then
        raw_syntax="$synopsis"
      else
        # Fallback: try to get usage from command itself
        local usage=$("$base_cmd" --help 2>&1 | grep -i "usage" | head -1 | sed 's/^[Uu]sage: //')
        if [ -n "$usage" ]; then
          raw_syntax="$usage"
        else
          raw_syntax="$base_cmd [options]"
        fi
      fi
    fi

    # Display colorized syntax
    if [ -n "$raw_syntax" ]; then
      local colored=$(colorize_syntax "$raw_syntax")
      printf "  %b\n" "$colored"
    fi
    echo ""

    # Add practical example
    echo -e "${CYAN}${BOLD}EXAMPLE:${NC}"
    local example=$(get_practical_example "$base_cmd")
    if [ -n "$example" ]; then
      echo -e "  ${GREEN}$example${NC}"
    fi
    echo ""
  fi

  # Try to find in database
  local found_in_db=false
  if check_jq && check_database; then
    local task=$(jq --arg cmd "$base_cmd" '.tasks[] | select(.command | contains($cmd))' "$DB_FILE" 2>/dev/null | jq -s '.[0]' 2>/dev/null)

    if [ -n "$task" ] && [ "$task" != "null" ] && [ "$task" != "" ]; then
      local desc=$(echo "$task" | jq -r '.description // empty' 2>/dev/null)
      if [ -n "$desc" ]; then
        echo -e "${GREEN}Description:${NC} $desc"
        echo ""
        found_in_db=true

        # Show flags if available
        local flags=$(echo "$task" | jq -r '.flags_explained // empty' 2>/dev/null)
        if [ -n "$flags" ] && [ "$flags" != "null" ]; then
          echo -e "${YELLOW}Flag explanations:${NC}"
          echo "$task" | jq -r '.flags_explained | to_entries[] | "  \(.key) : \(.value)"' 2>/dev/null
          echo ""
        fi
      fi
    fi
  fi

  # Fall back to man page if not found in database
  if [ "$found_in_db" = false ]; then
    if command -v "$base_cmd" &> /dev/null || type "$base_cmd" 2>/dev/null | grep -q "shell builtin"; then
      echo -e "${YELLOW}Getting help from man page...${NC}"
      echo ""

      if type "$base_cmd" 2>/dev/null | grep -q "shell builtin"; then
        help "$base_cmd" 2>/dev/null | head -20
      else
        man "$base_cmd" 2>/dev/null | col -b | head -30
      fi
    else
      echo -e "${RED}Command not found:${NC} $base_cmd"
    fi
  fi

  echo ""
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
}

# Get quick syntax for a command
get_quick_syntax() {
  local cmd="$1"
  local syntax=""

  if type "$cmd" 2>/dev/null | grep -q "shell builtin"; then
    syntax=$(help "$cmd" 2>/dev/null | head -1 | sed 's/^[[:space:]]*//' | cut -c1-60)
  else
    # Try to get first line from man page SYNOPSIS
    syntax=$(man "$cmd" 2>/dev/null | col -b | sed -n '/^SYNOPSIS/,/^DESCRIPTION/p' | sed -n '2p' | sed 's/^[[:space:]]*//' | cut -c1-60)

    if [ -z "$syntax" ]; then
      # Fallback to --help
      syntax=$("$cmd" --help 2>&1 | grep -i "usage" | head -1 | sed 's/^[Uu]sage: //' | cut -c1-60)
    fi

    if [ -z "$syntax" ]; then
      syntax="$cmd [options]"
    fi
  fi

  echo "$syntax"
}

# Get practical example for a command
get_practical_example() {
  local cmd="$1"
  local example=""

  case "$cmd" in
    # File Operations
    ls) example="ls -lah                    # List all files with human-readable sizes";;
    cd) example="cd /path/to/directory      # Change to a directory";;
    cp) example="cp file.txt backup.txt     # Copy a file";;
    mv) example="mv old.txt new.txt         # Rename or move a file";;
    rm) example="rm file.txt                # Delete a file";;
    mkdir) example="mkdir new_folder         # Create a new directory";;
    touch) example="touch newfile.txt        # Create an empty file";;
    cat) example="cat file.txt              # Display file contents";;
    chmod) example="chmod 755 script.sh      # Make a script executable";;
    chown) example="chown user:group file    # Change file owner";;
    ln) example="ln -s /path/to/file link   # Create a symbolic link";;

    # Text Processing
    grep) example="grep 'pattern' file.txt   # Search for text in a file";;
    sed) example="sed 's/old/new/g' file    # Replace text in a file";;
    awk) example="awk '{print \$1}' file     # Print first column";;
    cut) example="cut -d',' -f1 file.csv    # Extract first column from CSV";;
    sort) example="sort file.txt             # Sort lines alphabetically";;
    uniq) example="sort file.txt | uniq      # Remove duplicate lines";;
    wc) example="wc -l file.txt             # Count lines in a file";;
    diff) example="diff file1.txt file2.txt # Compare two files";;

    # File Search
    find) example="find . -name '*.txt'      # Find all .txt files";;
    locate) example="locate filename          # Quickly find a file";;
    which) example="which python              # Show full path of command";;

    # Compression
    tar) example="tar -czf archive.tar.gz folder/  # Compress a folder";;
    gzip) example="gzip file.txt             # Compress a file";;
    gunzip) example="gunzip file.txt.gz       # Decompress a file";;
    zip) example="zip archive.zip file1.txt file2.txt  # Create zip archive";;
    unzip) example="unzip archive.zip         # Extract zip archive";;

    # Network
    ping) example="ping google.com            # Test network connectivity";;
    curl) example="curl https://example.com   # Download webpage";;
    wget) example="wget https://example.com/file.zip  # Download a file";;
    ssh) example="ssh user@hostname          # Connect to remote server";;
    scp) example="scp file.txt user@host:/path/  # Copy file to remote server";;

    # System Info
    top) example="top                        # Monitor system processes";;
    ps) example="ps aux                     # List all running processes";;
    df) example="df -h                      # Show disk space usage";;
    du) example="du -sh folder/             # Show folder size";;
    free) example="free -h                    # Show memory usage";;
    uname) example="uname -a                   # Show system information";;

    # Process Management
    kill) example="kill 1234                  # Terminate process with PID 1234";;
    pkill) example="pkill firefox              # Kill all firefox processes";;

    # System Control
    sudo) example="sudo apt update            # Run command as root";;
    systemctl) example="systemctl status nginx  # Check service status";;

    # Package Management
    apt) example="apt install package        # Install a package";;
    dpkg) example="dpkg -i package.deb        # Install .deb package";;

    # Misc
    echo) example="echo 'Hello World'         # Print text to screen";;
    date) example="date '+%Y-%m-%d'           # Show current date";;
    history) example="history                   # Show command history";;
    man) example="man ls                     # Show manual for 'ls' command";;
    *)
      # Generic fallback
      example="$cmd --help                 # Show help for $cmd"
      ;;
  esac

  echo "$example"
}

# Colorize syntax elements by type for instant recognition
# Returns raw string with ANSI codes (caller should use echo -e or printf %b)
colorize_syntax() {
  local syntax="$1"
  local colored_syntax="$syntax"

  # Color scheme for syntax elements:
  # - Command name (first word): Bright cyan + bold
  # - [OPTIONS], [OPTION], etc.: Yellow
  # - UPPERCASE args (FILE, STRING, SET1, etc.): Magenta
  # - Lowercase/optional args: Green
  # - ... (ellipsis): Dim white

  # Extract command name (first word) - escape special chars for sed
  local cmd_word=$(echo "$syntax" | awk '{print $1}' | sed 's/[]\/$*.^[]/\\&/g')

  # Start with command in bright cyan + bold
  colored_syntax=$(echo "$syntax" | sed "s/^$cmd_word/\\\\033[0;36m\\\\033[1m$cmd_word\\\\033[0m/")

  # Color [OPTIONS], [OPTION], [EXPRESSION], etc. in yellow
  colored_syntax=$(echo "$colored_syntax" | sed -E "s/\[([A-Z][A-Z_-]*)\]/[\\\\033[0;33m\1\\\\033[0m]/g")

  # Color UPPERCASE arguments in magenta (FILE, STRING, PATH, SET1, etc.)
  colored_syntax=$(echo "$colored_syntax" | sed -E "s/([[:space:]])([A-Z][A-Z0-9_-]*[A-Z])([[:space:][:punct:]$])/\1\\\\033[0;35m\2\\\\033[0m\3/g")

  # Color lowercase optional arguments in green
  colored_syntax=$(echo "$colored_syntax" | sed -E "s/\[([a-z][a-z-]*)\]/[\\\\033[0;32m\1\\\\033[0m]/g")

  # Color ellipsis (...) in dim white
  colored_syntax=$(echo "$colored_syntax" | sed "s/\.\.\./\\\\033[2m...\\\\033[0m/g")

  # Return raw string (no echo -e, let caller handle interpretation)
  printf "%s" "$colored_syntax"
}

# Extract flags with descriptions from man pages
# New enhanced version that includes what each flag does
extract_all_flags() {
  local cmd_name="$1"
  local flags_output=""

  if type "$cmd_name" 2>/dev/null | grep -q "shell builtin"; then
    # Shell builtin - parse the "Options:" block from `help`, formatting each
    # entry as "flag — description" to match the man-page output below.
    flags_output=$(help "$cmd_name" 2>/dev/null | awk '
      /^[[:space:]]+-/ {
        line=$0; sub(/^[[:space:]]+/, "", line);
        if (match(line, /[ ][ ]+|\t/)) {
          flag=substr(line,1,RSTART-1);
          desc=substr(line,RSTART+RLENGTH); gsub(/^[[:space:]]+|[[:space:]]+$/,"",desc);
          printf "\033[1;33m%s\033[0m \033[2m—\033[0m %s\n", flag, desc;
        } else {
          printf "\033[1;33m%s\033[0m\n", line;
        }
      }')
  elif command -v "$cmd_name" &> /dev/null; then
    # External command - parse the FULL man page. Instead of reading a single
    # section (the old behaviour, which truncated curl/find/ps/git/tar/... to a
    # handful of flags), classify every section as option-bearing or not, then
    # extract every flag with its description across all option sections.
    # `col -bx` normalises tabs to spaces so indentation can be compared.
    local man_content=$(man "$cmd_name" 2>/dev/null | col -bx)

    if [ -n "$man_content" ]; then
      flags_output=$(printf '%s\n' "$man_content" | awk '
        { lines[++N]=$0; }
        END {
          # --- pre-pass: mark which sections actually contain option tags ---
          secid=0;
          for (i=1; i<=N; i++) {
            raw=lines[i];
            if (raw ~ /^[A-Z]/) { secid++; sname[secid]=fw(raw); }
            lsec[i]=secid;
            if (taglike(i)) tcount[secid]++;
          }
          for (s=1; s<=secid; s++)
            secscan[s] = (sname[s] ~ /^OPTION/ || tcount[s] >= 3) ? 1 : 0;

          # --- main pass: emit "flag — description" for every option ---
          flag=""; desc=""; curind=-1;
          for (i=1; i<=N; i++) {
            raw=lines[i];
            if (raw ~ /^[[:space:]]*$/) continue;                 # blank line
            if (raw ~ /^[A-Z]/) { flush(); curind=-1; continue; } # section header
            if (!secscan[lsec[i]]) continue;                      # skip prose sections
            ind = match(raw, /[^ ]/) - 1;
            t = raw; sub(/^[ ]+/, "", t);

            if (t ~ /^-/) {
              if (ncommaopt(t) >= 3) {                            # comma-list prose, not a tag
                if (flag != "" && ind > curind) adddesc(t);
                continue;
              }
              if (flag != "" && ind > curind) { adddesc(t); continue; }   # wrapped desc line
              if (flag != "" && desc == "" && ind == curind) {            # stacked alias
                if (match(t, /  +/)) { flag=flag", "substr(t,1,RSTART-1); desc=trim(substr(t,RSTART+RLENGTH)); }
                else                 { flag=flag", "t; }
                continue;
              }
              if (match(t, /  +/)) {                              # description on same line
                start_flag(substr(t,1,RSTART-1), trim(substr(t,RSTART+RLENGTH)), ind); continue;
              }
              j=i+1; while (j<=N && lines[j] ~ /^[[:space:]]*$/) j++;      # look ahead
              deeper = (j<=N && (match(lines[j],/[^ ]/)-1) > ind && trim(lines[j]) !~ /^-/);
              if (deeper) { start_flag(t, "", ind); continue; }   # description on next line(s)
              split_tag(t, ind); continue;                        # single-space inline desc
            }
            if (flag != "") adddesc(t);                           # description continuation
          }
          flush();
        }
        function fw(s,  w){ w=s; sub(/[[:space:]].*$/, "", w); return w; }
        function ncommaopt(s,  c,tmp){ tmp=s; c=gsub(/, +--?[A-Za-z]/, "", tmp); return c; }
        function trim(s){ gsub(/^[[:space:]]+|[[:space:]]+$/, "", s); return s; }
        function adddesc(s){ desc = (desc=="") ? trim(s) : desc" "trim(s); }
        function start_flag(sig, d, k){ flush(); flag=sig; desc=d; curind=k; }
        function taglike(i,  raw,t,ind,j,nind){
          raw=lines[i];
          if (raw !~ /^[ ]+-/) return 0;
          if (raw ~ /^[ ]+-{1,2}[A-Za-z0-9?][A-Za-z0-9?+._=-]*  /) return 1;
          ind = match(raw,/[^ ]/)-1;
          j=i+1; while (j<=N && lines[j] ~ /^[[:space:]]*$/) j++;
          if (j<=N) { nind=match(lines[j],/[^ ]/)-1; if (nind>ind && trim(lines[j]) !~ /^-/) return 1; }
          return 0;
        }
        function split_tag(s, k,   n,toks,p,tk,optend,sig,d){
          n=split(s,toks,/[ ]+/); optend=0;
          for (p=1;p<=n;p++){ tk=toks[p];
            if (tk ~ /^-/) { optend=p; continue; }
            if (tk ~ /^[A-Z0-9][A-Z0-9_<>|.=-]*[,]?$/) { optend=p; continue; }
            if (tk ~ /^[<\[]/) { optend=p; continue; }
            break;
          }
          if (optend==0) optend=1;
          sig=""; for(p=1;p<=optend;p++) sig=(sig=="")?toks[p]:sig" "toks[p];
          d="";   for(p=optend+1;p<=n;p++) d=(d=="")?toks[p]:d" "toks[p];
          start_flag(sig, d, k);
        }
        function flush(){
          if (flag != "") {
            desc=trim(desc);
            if (desc != "") printf "\033[1;33m%s\033[0m \033[2m—\033[0m %s\n", flag, desc;
            else printf "\033[1;33m%s\033[0m\n", flag;
          }
          flag=""; desc="";
        }
      ')
    fi

    # Fallback: nothing parsed (e.g. no man page) - grab raw flag lines
    if [ -z "$flags_output" ]; then
      flags_output=$(printf '%s\n' "$man_content" | grep -E '^[[:space:]]*-' | head -100)
    fi
  fi

  echo "$flags_output"
}

# Interactive flag browser with fuzzy search
# Now includes syntax and description in the fzf interface itself
browse_flags_fuzzy() {
  local cmd_name="$1"
  local cmd_syntax="$2"
  local cmd_desc="$3"

  # Extract all flags silently
  local all_flags=$(extract_all_flags "$cmd_name")

  if [ -z "$all_flags" ]; then
    echo ""
    echo -e "${RED}No flags found for: $cmd_name${NC}"
    echo ""
    return 1
  fi

  # Count flags
  local flag_count=$(echo "$all_flags" | wc -l)

  # Colorize the syntax for the header
  # colorize_syntax now returns raw \033 codes that printf %b will interpret
  local colored_syntax=$(colorize_syntax "$cmd_syntax")

  # Create multi-line header with command info using printf %b for proper escape code interpretation
  # Use actual ANSI codes for command and description, use %b for colored syntax
  local header
  printf -v header "╔═══════════════════════════════════════════════════════════════════════════════╗\n║ Command: \033[0;36m\033[1m%s\033[0m\n║ Syntax:  %b\n║ Desc:    \033[0;32m%s\033[0m\n╚═══════════════════════════════════════════════════════════════════════════════╝\n🔍 Fuzzy search %d flags | Multi-select: Ctrl-A/D | Esc: Back to menu" \
    "$cmd_name" \
    "$colored_syntax" \
    "$cmd_desc" \
    "$flag_count"

  # Show in fzf with integrated command info and enhanced bottom display
  echo "$all_flags" | fzf \
    --height 95% \
    --border=none \
    --header "$header" \
    --preview 'line=$(echo {} | sed -E "s/\x1b\[[0-9;]*m//g");
               if echo "$line" | grep -qF " — "; then
                 flag=$(echo "$line" | awk -F " — " "{print \$1}" | sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//");
                 desc=$(echo "$line" | awk -F " — " "{for(i=2;i<=NF;i++) printf \"%s \", \$i; print \"\"}" | sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//");
               else
                 flag=$(echo "$line" | sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//");
                 desc="(No description available)";
               fi;
               if [ -z "$desc" ] || [ "$desc" = "$flag" ]; then
                 desc="(No description available)";
               fi;
               echo "┌─────────────────────────────────────────────────────────────────────────────┐";
               printf "│ 🏴  Flag:  \033[1;36m%-66s\033[0m│\n" "$flag";
               echo "├─────────────────────────────────────────────────────────────────────────────┤";
               echo "│ 📝  Description:                                                            │";
               if [ "$desc" != "(No description available)" ]; then
                 echo "$desc" | fold -s -w 72 | while IFS= read -r dline; do
                   printf "│    \033[0;32m%-72s\033[0m│\n" "$dline";
                 done;
               else
                 printf "│    \033[2;37m%-72s\033[0m│\n" "$desc";
               fi;
               echo "└─────────────────────────────────────────────────────────────────────────────┘"' \
    --preview-window=down:8:wrap \
    --prompt "⚡ Search: " \
    --multi \
    --bind 'ctrl-a:select-all' \
    --bind 'ctrl-d:deselect-all' \
    --ansi \
    --color=header:bold:cyan

  return 0
}

show_flags() {
  CMD_NAME=$1
  CMD_SYNTAX=$2
  CMD_DESC=$3

  # Extract syntax if not provided
  if [ -z "$CMD_SYNTAX" ]; then
    if type "$CMD_NAME" 2>/dev/null | grep -q "shell builtin"; then
      # For builtins, get the first line of help
      CMD_SYNTAX=$(help "$CMD_NAME" 2>/dev/null | head -1 | sed 's/^[[:space:]]*//')
      [ -z "$CMD_SYNTAX" ] && CMD_SYNTAX="$CMD_NAME [options]"
    else
      # For regular commands, extract SYNOPSIS section from man page
      local synopsis=$(man "$CMD_NAME" 2>/dev/null | col -b | sed -n '/^SYNOPSIS/,/^DESCRIPTION/p' | head -15 | tail -n +2 | head -n -1 | tr '\n' ' ' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
      if [ -n "$synopsis" ]; then
        CMD_SYNTAX="$synopsis"
      else
        # Fallback: try to get usage from command itself
        local usage=$("$CMD_NAME" --help 2>&1 | grep -i "usage" | head -1 | sed 's/^[Uu]sage: //')
        if [ -n "$usage" ]; then
          CMD_SYNTAX="$usage"
        else
          CMD_SYNTAX="$CMD_NAME [options]"
        fi
      fi
    fi
  fi

  # Default description if not provided
  [ -z "$CMD_DESC" ] && CMD_DESC="No description available"

  # Directly open fuzzy flag browser with integrated command info (no wasted space)
  browse_flags_fuzzy "$CMD_NAME" "$CMD_SYNTAX" "$CMD_DESC"

  echo ""
  echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}

list_commands() {
  echo "Available commands:"
  echo ""
  for cmd in "${COMMANDS[@]}"; do
    CMD_NAME=${cmd%%:*}
    REST=${cmd#*:}

    # Extract description (before pipe) and syntax (after pipe)
    if [[ "$REST" =~ (.+)\ \|\ (.+) ]]; then
      DESC="${BASH_REMATCH[1]}"
      SYNTAX="${BASH_REMATCH[2]}"
      printf "  %-10s - %-40s | %s\n" "$CMD_NAME" "$DESC" "$SYNTAX"
    else
      printf "  %-10s - %s\n" "$CMD_NAME" "$REST"
    fi
  done
}

get_command_description() {
  local search_cmd=$1
  for cmd in "${COMMANDS[@]}"; do
    CMD_NAME=${cmd%%:*}
    REST=${cmd#*:}
    if [ "$CMD_NAME" = "$search_cmd" ]; then
      # Extract just the description part (before the pipe)
      if [[ "$REST" =~ (.+)\ \|\ (.+) ]]; then
        echo "${BASH_REMATCH[1]}"
      else
        echo "$REST"
      fi
      return 0
    fi
  done
  echo "Command help"
}

# Command definitions for interactive mode (format: "cmd:Description | Syntax")
COMMANDS=(
  # File Operations
  "ls:List directory contents | ls [OPTION]... [FILE]..."
  "cd:Change the current directory | cd [DIRECTORY]"
  "pwd:Print the name of the current working directory | pwd [OPTION]"
  "cp:Copy files and directories | cp [OPTION]... SOURCE DEST"
  "mv:Move or rename files and directories | mv [OPTION]... SOURCE DEST"
  "rm:Remove files or directories | rm [OPTION]... FILE..."
  "mkdir:Create a new directory | mkdir [OPTION]... DIRECTORY..."
  "rmdir:Remove an empty directory | rmdir [OPTION]... DIRECTORY..."
  "touch:Create empty file or update timestamp | touch [OPTION]... FILE..."
  "cat:Concatenate and display files | cat [OPTION]... [FILE]..."
  "less:View file contents with pagination | less [OPTION]... [FILE]..."
  "head:Display first lines of a file | head [OPTION]... [FILE]..."
  "tail:Display last lines of a file | tail [OPTION]... [FILE]..."
  "chmod:Change file permissions | chmod [OPTION] MODE FILE..."
  "chown:Change file owner | chown [OPTION]... OWNER[:GROUP] FILE..."
  "ln:Create links between files | ln [OPTION]... TARGET LINK_NAME"
  "file:Determine file type | file [OPTION]... FILE..."
  "stat:Display file status | stat [OPTION]... FILE..."

  # Text Processing
  "grep:Search for patterns in files | grep [OPTION]... PATTERN [FILE]..."
  "sed:Stream editor for text manipulation | sed [OPTION]... SCRIPT [FILE]..."
  "awk:Pattern scanning and text processing | awk [OPTION]... PROGRAM [FILE]..."
  "cut:Remove sections from lines of files | cut [OPTION]... [FILE]..."
  "sort:Sort lines of text | sort [OPTION]... [FILE]..."
  "uniq:Report or filter out repeated lines | uniq [OPTION]... [FILE]..."
  "tr:Translate or delete characters | tr [OPTION]... SET1 [SET2]"
  "wc:Count lines, words, and characters | wc [OPTION]... [FILE]..."
  "diff:Compare files line by line | diff [OPTION]... FILE1 FILE2"

  # File Search
  "find:Search for files in directory hierarchy | find [PATH] [OPTIONS] [EXPRESSION]"
  "locate:Find files by name quickly | locate [OPTION]... PATTERN..."
  "which:Show full path of commands | which [OPTION]... COMMAND..."
  "whereis:Locate binary, source, and manual pages | whereis [OPTION]... COMMAND..."

  # Compression
  "tar:Archive files | tar [OPTION]... [FILE]..."
  "gzip:Compress files | gzip [OPTION]... [FILE]..."
  "gunzip:Decompress gzip files | gunzip [OPTION]... [FILE]..."
  "zip:Package and compress files | zip [OPTION]... ZIPFILE FILES..."
  "unzip:Extract compressed zip files | unzip [OPTION]... FILE..."

  # Network
  "ping:Test network connectivity | ping [OPTION]... HOST"
  "curl:Transfer data from URLs | curl [OPTION]... URL..."
  "wget:Download files from the web | wget [OPTION]... URL..."
  "ssh:Secure shell remote login | ssh [OPTION]... USER@HOST [COMMAND]"
  "scp:Secure copy files between hosts | scp [OPTION]... SOURCE DEST"
  "netstat:Network statistics | netstat [OPTION]..."
  "ss:Socket statistics | ss [OPTION]..."
  "ip:Show/manipulate routing and devices | ip [OPTION]... OBJECT {COMMAND}"
  "ifconfig:Configure network interfaces | ifconfig [INTERFACE] [OPTIONS]"

  # System Info
  "top:Display system processes | top [OPTION]..."
  "htop:Interactive process viewer | htop [OPTION]..."
  "ps:Report process status | ps [OPTION]..."
  "df:Show disk space usage | df [OPTION]... [FILE]..."
  "du:Estimate file space usage | du [OPTION]... [FILE]..."
  "free:Display memory usage | free [OPTION]..."
  "uname:Print system information | uname [OPTION]..."
  "uptime:Show how long system has been running | uptime [OPTION]..."

  # Process Management
  "kill:Send signal to a process | kill [OPTION]... PID..."
  "pkill:Kill processes by name | pkill [OPTION]... PATTERN"
  "killall:Kill processes by name | killall [OPTION]... NAME..."
  "bg:Put job in background | bg [JOB_SPEC]"
  "fg:Bring job to foreground | fg [JOB_SPEC]"
  "jobs:List active jobs | jobs [OPTION]..."

  # System Control
  "sudo:Execute command as another user | sudo [OPTION]... COMMAND"
  "systemctl:Control systemd services | systemctl [OPTION]... COMMAND"
  "service:Control system services | service COMMAND [OPTIONS]"
  "reboot:Reboot the system | reboot [OPTION]..."
  "shutdown:Shut down the system | shutdown [OPTION]... [TIME]"

  # Package Management
  "apt:Package manager (Debian/Ubuntu) | apt [OPTION]... COMMAND"
  "apt-get:APT package handling utility | apt-get [OPTION]... COMMAND"
  "dpkg:Debian package manager | dpkg [OPTION]... ACTION"
  "snap:Snap package manager | snap [OPTION]... COMMAND"

  # User Management
  "useradd:Create new user | useradd [OPTION]... LOGIN"
  "userdel:Delete user account | userdel [OPTION]... LOGIN"
  "passwd:Change user password | passwd [OPTION]... [USER]"
  "su:Switch user | su [OPTION]... [USER]"
  "whoami:Print current username | whoami"
  "w:Show who is logged in | w [OPTION]... [USER]"
  "who:Show who is logged in | who [OPTION]..."

  # Misc Utilities
  "echo:Display a line of text | echo [OPTION]... [STRING]..."
  "date:Display or set system date and time | date [OPTION]... [+FORMAT]"
  "cal:Display calendar | cal [OPTION]... [[MONTH] YEAR]"
  "history:Show command history | history [n]"
  "alias:Create command aliases | alias [NAME[=VALUE]...]"
  "export:Set environment variables | export [NAME[=VALUE]...]"
  "env:Display environment variables | env [OPTION]... [NAME=VALUE]... [COMMAND]"
  "man:Display manual pages | man [OPTION]... [SECTION] PAGE"
  "watch:Execute command periodically | watch [OPTION]... COMMAND"

  # File Operations (extended)
  "dd:Convert and copy a file (block-level) | dd if=SOURCE of=DEST [OPERAND]..."
  "shred:Overwrite a file to securely delete it | shred [OPTION]... FILE..."
  "truncate:Shrink or extend file size | truncate [OPTION]... -s SIZE FILE..."
  "mktemp:Create a temporary file or directory | mktemp [OPTION]... [TEMPLATE]"
  "mkfifo:Create a named pipe (FIFO) | mkfifo [OPTION]... NAME..."
  "install:Copy files and set attributes | install [OPTION]... SOURCE DEST"
  "basename:Strip directory and suffix from a path | basename NAME [SUFFIX]"
  "dirname:Strip last component from a path | dirname [OPTION] NAME..."
  "realpath:Print the resolved absolute path | realpath [OPTION]... FILE..."
  "readlink:Print resolved symbolic link target | readlink [OPTION]... FILE..."
  "tree:List directory contents as a tree | tree [OPTION]... [DIRECTORY]"
  "rsync:Fast incremental file transfer/sync | rsync [OPTION]... SOURCE DEST"
  "pushd:Push directory onto the stack | pushd [DIRECTORY]"
  "popd:Pop directory off the stack | popd [+N|-N]"
  "rename:Rename multiple files via pattern | rename [OPTION]... EXPRESSION FILE..."

  # Text Processing (extended)
  "tee:Read stdin and write to files and stdout | tee [OPTION]... [FILE]..."
  "tac:Concatenate and print files in reverse | tac [OPTION]... [FILE]..."
  "nl:Number lines of files | nl [OPTION]... [FILE]..."
  "fold:Wrap lines to a fixed width | fold [OPTION]... [FILE]..."
  "fmt:Reformat paragraph text | fmt [OPTION]... [FILE]..."
  "paste:Merge lines of files side by side | paste [OPTION]... [FILE]..."
  "join:Join lines of two files on a field | join [OPTION]... FILE1 FILE2"
  "comm:Compare two sorted files line by line | comm [OPTION]... FILE1 FILE2"
  "column:Format input into columns | column [OPTION]... [FILE]..."
  "expand:Convert tabs to spaces | expand [OPTION]... [FILE]..."
  "unexpand:Convert spaces to tabs | unexpand [OPTION]... [FILE]..."
  "rev:Reverse characters in each line | rev [OPTION]... [FILE]..."
  "split:Split a file into pieces | split [OPTION]... [FILE [PREFIX]]"
  "csplit:Split a file by context lines | csplit [OPTION]... FILE PATTERN..."
  "od:Dump files in octal/other formats | od [OPTION]... [FILE]..."
  "hexdump:Display file contents in hex | hexdump [OPTION]... [FILE]..."
  "xxd:Make a hexdump or reverse it | xxd [OPTION]... [FILE]"
  "strings:Print printable strings in a file | strings [OPTION]... [FILE]..."
  "iconv:Convert text between encodings | iconv [OPTION]... [FILE]..."
  "jq:Process and query JSON data | jq [OPTION]... FILTER [FILE]..."
  "pr:Paginate/columnate files for printing | pr [OPTION]... [FILE]..."
  "printf:Format and print data | printf FORMAT [ARGUMENT]..."

  # File Search (extended)
  "type:Describe how a command name is resolved | type [OPTION]... NAME..."
  "command:Run a command bypassing aliases | command [OPTION]... NAME [ARG]..."
  "apropos:Search the manual page names | apropos [OPTION]... KEYWORD..."
  "updatedb:Update the locate file database | updatedb [OPTION]..."
  "xargs:Build and execute commands from stdin | xargs [OPTION]... [COMMAND]"

  # Compression (extended)
  "bzip2:Compress files with bzip2 | bzip2 [OPTION]... [FILE]..."
  "bunzip2:Decompress bzip2 files | bunzip2 [OPTION]... [FILE]..."
  "xz:Compress files with xz/LZMA | xz [OPTION]... [FILE]..."
  "unxz:Decompress xz files | unxz [OPTION]... [FILE]..."
  "zcat:Print gzip-compressed files | zcat [OPTION]... [FILE]..."
  "zstd:Compress files with Zstandard | zstd [OPTION]... [FILE]..."
  "7z:7-Zip archive manager | 7z COMMAND [OPTION]... ARCHIVE [FILE]..."
  "cpio:Copy files to/from archives | cpio [OPTION]..."

  # Network (extended)
  "dig:DNS lookup utility | dig [OPTION]... [@SERVER] NAME [TYPE]"
  "nslookup:Query DNS records interactively | nslookup [OPTION]... [HOST] [SERVER]"
  "host:DNS lookup utility (simple) | host [OPTION]... NAME [SERVER]"
  "traceroute:Trace route packets take to a host | traceroute [OPTION]... HOST"
  "mtr:Combined traceroute and ping tool | mtr [OPTION]... HOST"
  "nc:Netcat - read/write network connections | nc [OPTION]... [HOST] [PORT]"
  "telnet:Connect to a host over Telnet | telnet [OPTION]... [HOST [PORT]]"
  "sftp:Secure file transfer over SSH | sftp [OPTION]... USER@HOST"
  "nmap:Network exploration and port scanner | nmap [OPTION]... TARGET..."
  "arp:Show/manipulate the ARP cache | arp [OPTION]..."
  "route:Show/manipulate the routing table | route [OPTION]..."
  "tcpdump:Capture and analyze network traffic | tcpdump [OPTION]... [EXPRESSION]"
  "iptables:Configure IPv4 packet filtering | iptables [OPTION]... CHAIN [RULE]"
  "ethtool:Query/control network driver settings | ethtool [OPTION]... DEVICE"
  "nmcli:Control NetworkManager from the CLI | nmcli [OPTION]... OBJECT {COMMAND}"
  "hostname:Show or set the system hostname | hostname [OPTION]... [NAME]"
  "whois:Look up domain/IP registration info | whois [OPTION]... OBJECT"
  "ssh-keygen:Generate/manage SSH keys | ssh-keygen [OPTION]..."

  # System Info (extended)
  "lscpu:Display CPU architecture information | lscpu [OPTION]..."
  "lsblk:List block devices | lsblk [OPTION]... [DEVICE]..."
  "lsusb:List USB devices | lsusb [OPTION]..."
  "lspci:List PCI devices | lspci [OPTION]..."
  "lsmod:Show status of kernel modules | lsmod"
  "lsof:List open files and the processes using them | lsof [OPTION]..."
  "vmstat:Report virtual memory statistics | vmstat [OPTION]... [DELAY [COUNT]]"
  "iostat:Report CPU and I/O statistics | iostat [OPTION]... [DELAY [COUNT]]"
  "dmidecode:Dump DMI/SMBIOS hardware table | dmidecode [OPTION]..."
  "dmesg:Print kernel ring buffer messages | dmesg [OPTION]..."
  "journalctl:Query the systemd journal | journalctl [OPTION]..."
  "timedatectl:Query/change system clock settings | timedatectl [OPTION]... [COMMAND]"
  "hostnamectl:Query/change system hostname | hostnamectl [OPTION]... [COMMAND]"
  "nproc:Print the number of processing units | nproc [OPTION]..."
  "sysctl:Read/modify kernel parameters | sysctl [OPTION]... [VARIABLE[=VALUE]]..."

  # Process Management (extended)
  "nice:Run a program with modified priority | nice [OPTION]... [COMMAND]"
  "renice:Alter priority of running processes | renice [OPTION]... PRIORITY PID..."
  "nohup:Run a command immune to hangups | nohup COMMAND [ARG]..."
  "disown:Remove jobs from the shell's job table | disown [OPTION]... [JOB]..."
  "pgrep:Find process IDs by name/attributes | pgrep [OPTION]... PATTERN"
  "pidof:Find the PID of a running program | pidof [OPTION]... PROGRAM..."
  "fuser:Identify processes using files/sockets | fuser [OPTION]... NAME..."
  "time:Time a command's execution | time [OPTION]... COMMAND"
  "timeout:Run a command with a time limit | timeout [OPTION]... DURATION COMMAND"
  "strace:Trace system calls and signals | strace [OPTION]... COMMAND"
  "ltrace:Trace library calls | ltrace [OPTION]... COMMAND"
  "at:Schedule a command for later | at [OPTION]... TIME"
  "crontab:Manage cron job schedules | crontab [OPTION]... [FILE]"
  "sleep:Pause for a specified duration | sleep NUMBER[SUFFIX]..."

  # System Control / Disk (extended)
  "mount:Mount a filesystem | mount [OPTION]... DEVICE DIR"
  "umount:Unmount a filesystem | umount [OPTION]... {DIR|DEVICE}"
  "fdisk:Manipulate disk partition tables | fdisk [OPTION]... DEVICE"
  "parted:Partition manipulation program | parted [OPTION]... [DEVICE [COMMAND]]"
  "mkfs:Build a Linux filesystem | mkfs [OPTION]... DEVICE"
  "fsck:Check and repair a filesystem | fsck [OPTION]... [DEVICE]..."
  "swapon:Enable devices/files for swapping | swapon [OPTION]... [DEVICE]"
  "swapoff:Disable swapping on devices/files | swapoff [OPTION]... [DEVICE]"
  "blkid:Locate/print block device attributes | blkid [OPTION]... [DEVICE]..."
  "sync:Flush filesystem buffers to disk | sync [OPTION]... [FILE]..."
  "modprobe:Add or remove kernel modules | modprobe [OPTION]... MODULE"
  "poweroff:Power off the machine | poweroff [OPTION]..."
  "ncdu:NCurses disk usage analyzer | ncdu [OPTION]... [DIRECTORY]"

  # Package Management (extended)
  "yum:Package manager (RHEL/CentOS) | yum [OPTION]... COMMAND"
  "dnf:Package manager (Fedora/RHEL) | dnf [OPTION]... COMMAND"
  "rpm:RPM package manager | rpm [OPTION]... PACKAGE..."
  "pacman:Package manager (Arch Linux) | pacman [OPTION]... [TARGET]..."
  "zypper:Package manager (openSUSE) | zypper [OPTION]... COMMAND"
  "flatpak:Manage Flatpak applications | flatpak [OPTION]... COMMAND"
  "pip:Python package installer | pip [OPTION]... COMMAND"
  "npm:Node.js package manager | npm [OPTION]... COMMAND"
  "apt-cache:Query the APT package cache | apt-cache [OPTION]... COMMAND"

  # User & Group Management (extended)
  "usermod:Modify a user account | usermod [OPTION]... LOGIN"
  "groupadd:Create a new group | groupadd [OPTION]... GROUP"
  "groupdel:Delete a group | groupdel [OPTION]... GROUP"
  "groupmod:Modify a group | groupmod [OPTION]... GROUP"
  "groups:Show groups a user belongs to | groups [USER]..."
  "id:Print user and group IDs | id [OPTION]... [USER]"
  "chage:Change user password expiry info | chage [OPTION]... LOGIN"
  "newgrp:Log in to a new group | newgrp [GROUP]"
  "last:Show last logged-in users | last [OPTION]... [NAME]..."
  "logname:Print the user's login name | logname"

  # Permissions & Security (extended)
  "umask:Set default file permission mask | umask [OPTION]... [MODE]"
  "chgrp:Change group ownership | chgrp [OPTION]... GROUP FILE..."
  "setfacl:Set file access control lists | setfacl [OPTION]... FILE..."
  "getfacl:Get file access control lists | getfacl [OPTION]... FILE..."
  "chattr:Change file attributes on Linux FS | chattr [OPTION]... [+-=MODE] FILE..."
  "lsattr:List file attributes on Linux FS | lsattr [OPTION]... [FILE]..."
  "gpg:Encrypt, sign, and manage keys | gpg [OPTION]... [FILE]..."
  "openssl:Cryptography and TLS toolkit | openssl COMMAND [OPTION]..."
  "md5sum:Compute/check MD5 checksums | md5sum [OPTION]... [FILE]..."
  "sha256sum:Compute/check SHA-256 checksums | sha256sum [OPTION]... [FILE]..."
  "sha1sum:Compute/check SHA-1 checksums | sha1sum [OPTION]... [FILE]..."
  "cksum:Compute CRC checksum and byte count | cksum [OPTION]... [FILE]..."
  "base64:Encode/decode data in base64 | base64 [OPTION]... [FILE]"

  # Shell & Scripting (extended)
  "read:Read a line into shell variables | read [OPTION]... [NAME]..."
  "test:Evaluate a conditional expression | test EXPRESSION"
  "eval:Evaluate arguments as a command | eval [ARG]..."
  "exec:Replace the shell with a command | exec [COMMAND [ARG]...]"
  "source:Execute commands from a file | source FILE [ARG]..."
  "set:Set shell options and positional params | set [OPTION]... [ARG]..."
  "unset:Unset shell variables or functions | unset [OPTION]... NAME..."
  "shift:Shift positional parameters | shift [N]"
  "getopts:Parse positional option arguments | getopts OPTSTRING NAME [ARG]..."
  "declare:Declare variables and attributes | declare [OPTION]... [NAME[=VALUE]]..."
  "trap:Run commands on signals/events | trap [OPTION]... [ARG] [SIGNAL]..."
  "ulimit:Set/show user resource limits | ulimit [OPTION]... [LIMIT]"
  "hash:Remember/show command locations | hash [OPTION]... [NAME]..."
  "true:Return a successful exit status | true"
  "false:Return an unsuccessful exit status | false"
  "seq:Print a sequence of numbers | seq [OPTION]... [FIRST [INC]] LAST"
  "yes:Repeatedly print a string | yes [STRING]..."
  "expr:Evaluate expressions | expr EXPRESSION"
  "bc:Arbitrary-precision calculator | bc [OPTION]... [FILE]..."
  "shuf:Generate random permutations | shuf [OPTION]... [FILE]"
  "factor:Print the prime factors of numbers | factor [NUMBER]..."

  # Terminal & Misc (extended)
  "clear:Clear the terminal screen | clear [OPTION]..."
  "reset:Reset the terminal to defaults | reset [OPTION]..."
  "tput:Query/set terminal capabilities | tput [OPTION]... CAPNAME [ARG]..."
  "stty:Change/print terminal line settings | stty [OPTION]... [SETTING]..."
  "tty:Print the terminal connected to stdin | tty [OPTION]..."
  "screen:Terminal multiplexer | screen [OPTION]... [COMMAND]"
  "tmux:Terminal multiplexer | tmux [OPTION]... [COMMAND]"
  "nano:Simple terminal text editor | nano [OPTION]... [FILE]..."
  "vim:Vi IMproved text editor | vim [OPTION]... [FILE]..."
  "xdg-open:Open a file/URL in the default app | xdg-open {FILE|URL}"
  "notify-send:Send a desktop notification | notify-send [OPTION]... TITLE [BODY]"
  "lolcat:Rainbow-colorize text output | lolcat [OPTION]... [FILE]..."
  "figlet:Render text as ASCII art banners | figlet [OPTION]... [MESSAGE]"
)

# Parse arguments
MODE=""
QUERY=""
INTERACTIVE=false
COMMAND=""
FILTER=""

if [ $# -eq 0 ]; then
  INTERACTIVE=true
else
  case "$1" in
    -h|--help)
      show_help
      exit 0
      ;;
    -l|--list)
      list_commands
      exit 0
      ;;
    -i|--interactive)
      INTERACTIVE=true
      ;;
    ask)
      MODE="ask"
      QUERY="$2"
      ;;
    task)
      MODE="task"
      QUERY="$2"
      ;;
    explain)
      MODE="explain"
      QUERY="$2"
      ;;
    category)
      MODE="category"
      QUERY="$2"
      ;;
    ai)
      shift
      mode_ai "$@"
      exit $?
      ;;
    -*)
      echo "Unknown option: $1"
      echo "Use --help for usage information"
      exit 1
      ;;
    *)
      COMMAND=$1
      FILTER=$2
      ;;
  esac
fi

# Handle new modes
if [ -n "$MODE" ]; then
  case "$MODE" in
    ask|task)
      mode_ask "$QUERY"
      exit $?
      ;;
    explain)
      mode_explain "$QUERY"
      exit $?
      ;;
    category)
      mode_category "$QUERY"
      exit $?
      ;;
  esac
fi

# Format commands for display - called once and cached for performance
format_commands_for_display() {
  # Get terminal width for proper alignment
  local term_width=$(tput cols 2>/dev/null || echo 120)

  # Conservative approach to prevent ANY clipping
  # Account for fzf border, padding, and any other overhead
  local safe_width=$((term_width - 6))  # 2 for border + 4 buffer for safety

  # Fixed 2-column layout: description on left, syntax on right
  # Prioritize syntax visibility - give it 50% of space
  local syntax_col_width=$((safe_width * 50 / 100))
  [ $syntax_col_width -lt 30 ] && syntax_col_width=30

  # Description gets the rest (with separator space)
  local desc_col_width=$((safe_width - syntax_col_width - 8))
  [ $desc_col_width -lt 25 ] && desc_col_width=25

  # Format all commands with fixed column widths
  FORMATTED_COMMANDS=()
  for cmd in "${COMMANDS[@]}"; do
    local cmd_name=${cmd%%:*}
    local rest=${cmd#*:}

    # Extract description and syntax
    local desc_part syntax_part
    if [[ "$rest" =~ (.+)\ \|\ (.+) ]]; then
      desc_part="${BASH_REMATCH[1]}"
      syntax_part="${BASH_REMATCH[2]}"
    else
      desc_part="$rest"
      syntax_part="$cmd_name [options]"
    fi

    # Truncate description to fit column (cmd: + desc)
    local cmd_desc_str="${cmd_name}: ${desc_part}"
    local max_cmd_desc_len=$desc_col_width

    if [ ${#cmd_desc_str} -gt $max_cmd_desc_len ]; then
      # Truncate description, keeping command name intact
      local desc_available=$((max_cmd_desc_len - ${#cmd_name} - 5))  # 2 for ": ", 3 for "..."
      if [ $desc_available -gt 10 ]; then
        desc_part="${desc_part:0:$desc_available}..."
      else
        desc_part="..."
      fi
      cmd_desc_str="${cmd_name}: ${desc_part}"
    fi

    # Truncate syntax to fit its column
    local plain_syntax="$syntax_part"
    if [ ${#syntax_part} -gt $syntax_col_width ]; then
      plain_syntax="${syntax_part:0:$((syntax_col_width-3))}..."
    fi

    # Colorize syntax after truncation
    local colorized_syntax=$(colorize_syntax "$plain_syntax")

    # Calculate padding to place syntax in its column
    local left_len=${#cmd_desc_str}
    local syntax_len=${#plain_syntax}

    # Place syntax at fixed position (right-aligned within safe width)
    local padding=$((safe_width - left_len - syntax_len - 2))
    [ $padding -lt 3 ] && padding=3

    local spaces=$(printf '%*s' "$padding" '')

    # Format line with colors
    local formatted_line="\033[0;36m${cmd_name}\033[0m: ${desc_part}${spaces}${colorized_syntax}"

    FORMATTED_COMMANDS+=("$formatted_line")
  done
}

# Interactive mode with fzf (loopable)
if [ "$INTERACTIVE" = true ]; then
  # Check if fzf is available
  if ! command -v fzf &> /dev/null; then
    echo "Error: fzf is not installed"
    echo "Install it with: sudo apt install fzf"
    echo ""
    echo "Or use direct mode: super-man COMMAND [FILTER]"
    exit 1
  fi

  # Format commands once before entering loop (performance optimization)
  format_commands_for_display

  # Set up window resize detection to trigger reformatting
  NEEDS_REFORMAT=false
  trap 'NEEDS_REFORMAT=true' WINCH

  # Main interactive loop
  while true; do
    # Reformat commands if terminal was resized
    if [ "$NEEDS_REFORMAT" = true ]; then
      format_commands_for_display
      NEEDS_REFORMAT=false
    fi

    # Show in fzf with formatted display
    SELECTED=$(printf "%b\n" "${FORMATTED_COMMANDS[@]}" | fzf \
      --height 60% \
      --border \
      --header "Select a command (Esc to exit) | Colorized: cmd=[cyan] [OPTIONS]=[yellow] FILE=[magenta]" \
      --prompt "🔍 Search: " \
      --preview-window=hidden \
      --ansi)

    if [ -z "$SELECTED" ]; then
      # User pressed Esc or cancelled
      echo ""
      echo -e "${YELLOW}Exiting Super Man. Happy coding! 👋${NC}"
      exit 0
    fi

    # Extract command name from selection (strip color codes)
    CMD=$(echo "$SELECTED" | sed 's/\x1b\[[0-9;]*m//g' | awk -F: '{print $1}' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')

    # Find the original command entry to get full details
    for cmd in "${COMMANDS[@]}"; do
      CMD_NAME=${cmd%%:*}
      if [ "$CMD_NAME" = "$CMD" ]; then
        REST=${cmd#*:}

        # Extract description and syntax
        if [[ "$REST" =~ (.+)\ \|\ (.+) ]]; then
          DESC="${BASH_REMATCH[1]}"
          SYNTAX="${BASH_REMATCH[2]}"
        else
          DESC="$REST"
          SYNTAX="$CMD [options]"
        fi
        break
      fi
    done

    # Directly show fuzzy flag browser with integrated command info (no wasted space)
    clear
    show_flags "$CMD" "$SYNTAX" "$DESC"

    # Esc in the flag browser returns straight to the home menu (no intermediary step)
    clear
  done
# Direct mode
elif [ -n "$COMMAND" ]; then
  # Validate command exists in our list
  FOUND=false
  DESC_PART=""
  SYNTAX_PART=""

  for cmd in "${COMMANDS[@]}"; do
    CMD_NAME=${cmd%%:*}
    if [ "$CMD_NAME" = "$COMMAND" ]; then
      FOUND=true
      REST=${cmd#*:}

      # Extract description and syntax
      if [[ "$REST" =~ (.+)\ \|\ (.+) ]]; then
        DESC_PART="${BASH_REMATCH[1]}"
        SYNTAX_PART="${BASH_REMATCH[2]}"
      else
        DESC_PART="$REST"
        SYNTAX_PART="$COMMAND [options]"
      fi
      break
    fi
  done

  if [ "$FOUND" = false ]; then
    echo "Warning: '$COMMAND' is not in the predefined list"
    echo "Available commands:"
    list_commands
    echo ""
    echo "Attempting to show flags anyway..."
    echo ""
    DESC_PART=$(get_command_description "$COMMAND")
    SYNTAX_PART="$COMMAND [options]"
  fi

  # Show command info in enhanced format
  echo ""
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo -e "${YELLOW}Command:${NC} ${MAGENTA}$COMMAND${NC}"
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo ""
  echo -e "${CYAN}${BOLD}SYNTAX:${NC}"
  echo -e "  ${GREEN}$SYNTAX_PART${NC}"
  echo ""
  echo -e "${GREEN}Description:${NC} $DESC_PART"
  echo ""
  echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
  echo ""

  show_flags "$COMMAND" "$FILTER"
else
  show_help
  exit 1
fi
