#!/usr/bin/env bash
set -euo pipefail

COMMAND="${1:-help}"

HERO_ID=""
TOWN_ID=""
LEVEL=""
GOLD=""
HP=""
LIMIT=20
OFFSET=0
N=""

BASE_URL="${ADMIN_BASE_URL:-http://localhost:8080}"
USERNAME="${ADMIN_BASIC_AUTH_USERNAME:-}"
PASSWORD="${ADMIN_BASIC_AUTH_PASSWORD:-}"

shift || true

show_help() {
  cat <<EOF
Usage:
  ./admin.sh <command> [options]

Commands:
  info
  heroes                [--limit N --offset N]
  hero                  --hero-id ID
  set-level             --hero-id ID --level N
  set-gold              --hero-id ID --gold N
  set-hp                --hero-id ID --hp N
  revive                --hero-id ID
  reset                 --hero-id ID
  reset-buffs           --hero-id ID
  add-potions           --hero-id ID --n N
  delete                --hero-id ID
  engine-status
  engine-combats
  ws-connections
  towns
  start-adventure       --hero-id ID
  teleport-town         --hero-id ID --town-id ID
  start-rest            --hero-id ID
  time-pause
  time-resume

Options:
  --hero-id ID
  --town-id ID
  --level N
  --gold N
  --hp N
  --limit N (default: 20)
  --offset N (default: 0)
  --n N

Env:
  ADMIN_BASE_URL
  ADMIN_BASIC_AUTH_USERNAME
  ADMIN_BASIC_AUTH_PASSWORD

Examples:
  ./admin.sh heroes --limit 50
  ./admin.sh hero --hero-id 123
  ./admin.sh set-level --hero-id 123 --level 10
EOF
}

# --- parse args ---
while [[ $# -gt 0 ]]; do
  case "$1" in
    --hero-id) HERO_ID="$2"; shift 2 ;;
    --town-id) TOWN_ID="$2"; shift 2 ;;
    --level) LEVEL="$2"; shift 2 ;;
    --gold) GOLD="$2"; shift 2 ;;
    --hp) HP="$2"; shift 2 ;;
    --limit) LIMIT="$2"; shift 2 ;;
    --offset) OFFSET="$2"; shift 2 ;;
    --n) N="$2"; shift 2 ;;
    --base-url) BASE_URL="$2"; shift 2 ;;
    --username) USERNAME="$2"; shift 2 ;;
    --password) PASSWORD="$2"; shift 2 ;;
    *) echo "Unknown arg: $1"; exit 1 ;;
  esac
done

if [[ -z "$USERNAME" || -z "$PASSWORD" ]]; then
  echo "Missing admin credentials. Set ADMIN_BASIC_AUTH_USERNAME and ADMIN_BASIC_AUTH_PASSWORD."
  exit 1
fi

require_value() {
  local name="$1"
  local value="$2"
  if [[ -z "$value" ]]; then
    echo "Parameter --$name is required for '$COMMAND'"
    exit 1
  fi
}

request() {
  local method="$1"
  local path="$2"
  local body="${3:-}"

  local url="${BASE_URL%/}${path}"

  if [[ -n "$body" ]]; then
    curl -sS -X "$method" "$url" \
      -u "$USERNAME:$PASSWORD" \
      -H "Accept: application/json" \
      -H "Content-Type: application/json" \
      -d "$body" | jq .
  else
    curl -sS -X "$method" "$url" \
      -u "$USERNAME:$PASSWORD" \
      -H "Accept: application/json" | jq .
  fi
}

case "$COMMAND" in
  help)
    show_help
    ;;
  info)
    request GET "/admin/info"
    ;;

  heroes)
    request GET "/admin/heroes?limit=$LIMIT&offset=$OFFSET"
    ;;

  hero)
    require_value "hero-id" "$HERO_ID"
    request GET "/admin/heroes/$HERO_ID"
    ;;

  set-level)
    require_value "hero-id" "$HERO_ID"
    require_value "level" "$LEVEL"
    request POST "/admin/heroes/$HERO_ID/set-level" \
      "{\"level\": $LEVEL}"
    ;;

  set-gold)
    require_value "hero-id" "$HERO_ID"
    require_value "gold" "$GOLD"
    request POST "/admin/heroes/$HERO_ID/set-gold" \
      "{\"gold\": $GOLD}"
    ;;

  set-hp)
    require_value "hero-id" "$HERO_ID"
    require_value "hp" "$HP"
    request POST "/admin/heroes/$HERO_ID/set-hp" \
      "{\"hp\": $HP}"
    ;;

  revive)
    require_value "hero-id" "$HERO_ID"
    request POST "/admin/heroes/$HERO_ID/revive" "{}"
    ;;

  reset)
    require_value "hero-id" "$HERO_ID"
    request POST "/admin/heroes/$HERO_ID/reset" "{}"
    ;;

  reset-buffs)
    require_value "hero-id" "$HERO_ID"
    request POST "/admin/heroes/$HERO_ID/reset-buff-charges" "{}"
    ;;

  add-potions)
    require_value "hero-id" "$HERO_ID"
    require_value "n" "$N"
    request POST "/admin/heroes/$HERO_ID/add-potions" \
      "{\"potions\": $N}"
    ;;

  delete)
    require_value "hero-id" "$HERO_ID"
    request DELETE "/admin/heroes/$HERO_ID"
    ;;

  engine-status)
    request GET "/admin/engine/status"
    ;;

  engine-combats)
    request GET "/admin/engine/combats"
    ;;

  ws-connections)
    request GET "/admin/ws/connections"
    ;;

  towns)
    request GET "/admin/towns"
    ;;

  start-adventure)
    require_value "hero-id" "$HERO_ID"
    request POST "/admin/heroes/$HERO_ID/start-adventure" "{}"
    ;;

  teleport-town)
    require_value "hero-id" "$HERO_ID"
    require_value "town-id" "$TOWN_ID"
    request POST "/admin/heroes/$HERO_ID/teleport-town" \
      "{\"townId\": $TOWN_ID}"
    ;;

  start-rest)
    require_value "hero-id" "$HERO_ID"
    request POST "/admin/heroes/$HERO_ID/start-rest" "{}"
    ;;

  time-pause)
    request POST "/admin/time/pause" "{}"
    ;;

  time-resume)
    request POST "/admin/time/resume" "{}"
    ;;

  *)
    echo "Unsupported command: $COMMAND"
    show_help
    exit 1
    ;;
esac