#!/usr/bin/env bash

# ============================================
# Private helpers
# ============================================

function cmd::shell::_prompt() {
  local user host dir
  user=$(whoami)
  host=$(hostname -s)
  dir=$(basename "$PWD")
  printf "\033[1;32m%s@%s\033[0m:\033[0;36m%s\033[0m \033[1;34mwgctl\033[0m> " \
    "$user" "$host" "$dir"
}

function cmd::shell::_is_wgctl_command() {
  local cmd="${1:-}"
  local known=(
    list add remove rm inspect block unblock
    rule group audit logs watch fw config qr
    rename keys ip net service shell help test
  )
  local c
  for c in "${known[@]}"; do
    [[ "$c" == "$cmd" ]] && return 0
  done
  return 1
}

function cmd::shell::_handle_builtin() {
  local input="${1:-}"
  local first="${input%% *}"

  case "$first" in
    cd)
      local dir="${input#cd }"
      [[ "$dir" == "$input" ]] && dir="$HOME"
      cd "$dir" 2>/dev/null || log::error "cd: $dir: No such file or directory"
      return 0
      ;;
    export|unset|source|.)
      eval "$input"
      return 0
      ;;
  esac
  return 1
}

function cmd::shell::_execute() {
  local input="${1:-}"
  local first="${input%% *}"
  local rest="${input#"$first"}"
  rest="${rest# }"

  cmd::shell::_handle_builtin "$input" && return 0

  if cmd::shell::_is_wgctl_command "$first"; then
    if [[ -n "$rest" ]]; then
      wgctl::dispatch "$first" $rest || true
    else
      wgctl::dispatch "$first" || true
    fi
    return 0
  fi

  bash -c "$input" || true
}

function cmd::shell::_setup_history() {
  HISTFILE="${HOME}/.wgctl_history"
  HISTSIZE=1000
  HISTFILESIZE=2000
  history -r 2>/dev/null || true
}

function cmd::shell::_save_history() {
  history -w 2>/dev/null || true
}

function cmd::shell::_banner() {
  ui::section "wgctl shell"
  printf "\n"
  printf "  Type wgctl commands directly (no 'wgctl' prefix).\n"
  printf "  Bash commands work too: ls, cat, systemctl, vim...\n\n"
  printf "  \033[1;37mCommon commands:\033[0m\n"
  printf "    list                         List all peers\n"
  printf "    list --blocked               Show blocked peers\n"
  printf "    list --restricted            Show restricted peers\n"
  printf "    list --rule user             Filter by rule\n"
  printf "    inspect --name <peer>        Full peer details\n"
  printf "    block --name <peer>          Block a peer entirely\n"
  printf "    block --name <peer> --service proxmox  Restrict service\n"
  printf "    unblock --name <peer>        Restore full access\n"
  printf "    rule list                    Show firewall rules\n"
  printf "    rule list --tree             Show with inheritance\n"
  printf "    rule show --name <rule>      Rule details\n"
  printf "    net list                     Show network services\n"
  printf "    net list --detailed          Show services with ports\n"
  printf "    group list                   Show groups\n"
  printf "    group block --name <group>   Block all peers in group\n"
  printf "    logs --follow                Live activity log\n"
  printf "    logs rotate                  Clean old log entries\n"
  printf "    watch                        Live WG + firewall monitor\n"
  printf "    fw list                      Show iptables rules\n"
  printf "    audit                        Verify firewall state\n"
  printf "    audit --fix                  Auto-repair firewall rules\n\n"
  printf "  \033[1mexit\033[0m or \033[1mquit\033[0m to leave  ·  \033[1mhelp\033[0m for full command list\n\n"
}

# ============================================
# Lifecycle
# ============================================

function cmd::shell::on_load() {
  : # no flags needed
}

function cmd::shell::help() {
  cat <<EOF
Usage: wgctl shell

Start an interactive wgctl shell.
All wgctl commands work directly (no 'wgctl' prefix needed).
Bash commands (ls, cat, systemctl, vim, etc.) also work.

Shell builtins handled natively: cd, export, unset, source
History saved to: ~/.wgctl_history

Examples:
  wgctl shell
  wgctl> list --blocked
  wgctl> inspect --name phone-nuno
  wgctl> rule list --tree
  wgctl> group block --name family
  wgctl> logs --follow
  wgctl> ls /etc/wireguard/.wgctl/rules/
  wgctl> exit
EOF
}

# ============================================
# Tab completion
# ============================================

function cmd::shell::_setup_completion() {
  local commands="list add remove rm inspect block unblock rule group audit logs watch fw config qr rename service shell help test"

  function _wgctl_shell_complete() {
    local cur="${COMP_WORDS[COMP_CWORD]}"
    COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
  }

  bind 'set show-all-if-ambiguous on' 2>/dev/null || true
  bind 'set completion-ignore-case on' 2>/dev/null || true
}

# ============================================
# Run
# ============================================

function cmd::shell::run() {
  cmd::shell::_banner
  cmd::shell::_setup_history
  cmd::shell::_setup_completion

  while true; do
    local input
    IFS= read -r -e -p "$(cmd::shell::_prompt)" input || break

    [[ -z "${input// }" ]] && continue

    history -s "$input"

    case "${input%% *}" in
      exit|quit) break ;;
    esac

    cmd::shell::_execute "$input"
  done

  cmd::shell::_save_history
  printf "\n  Goodbye!\n\n"
}