#!/usr/bin/env bash
# avatar — 3D talking avatar overlay CLI
AV_PORT="${AV_PORT:-8771}"
AV_URL="http://127.0.0.1:$AV_PORT"
TTS_URL="http://127.0.0.1:8840"

post() {
  curl -sf -X POST "$AV_URL" -H 'Content-Type: application/json' -d "$1" 2>/dev/null
}

# URL-encode via python (handles apostrophes etc)
urlencode() { printf '%s' "$1" | python3 -c "import sys,urllib.parse;print(urllib.parse.quote(sys.stdin.read()))"; }

avatar_say() {
  local text="$1"
  local save_dir="$2"
  local escaped
  escaped=$(printf '%s' "$text" | sed 's/\\/\\\\/g; s/"/\\"/g')
  local encoded
  encoded=$(urlencode "$text")

  if [ -n "$save_dir" ]; then
    # Save mode: save WAV + get amplitude envelope, then replay amplitudes frame-by-frame
    local idx
    idx=$(ls "$save_dir"/phrase-*.wav 2>/dev/null | wc -l)
    local outfile="$save_dir/phrase-$(printf '%03d' "$idx").wav"
    local resp
    resp=$(curl -sf "$TTS_URL/tts-save?text=$encoded&out=$outfile" 2>/dev/null)

    # Send amplitude frames at 30fps for exact lip-sync
    # Also tell viewer to start (it won't play audio, we just drive the mouth)
    python3 -c "
import json, time, sys, urllib.request
data = json.loads('''$resp''') if '''$resp''' else {'duration': 2, 'amplitudes': []}
amps = data.get('amplitudes', [])
duration = data.get('duration', 2)
av = '$AV_URL'

# Send avatar_show (mouth will be driven by amplitude messages)
def send_amp(a):
    body = json.dumps({'action':'avatar_say_amp','amplitude': a}).encode()
    req = urllib.request.Request(av, body, {'Content-Type':'application/json'})
    try: urllib.request.urlopen(req, timeout=0.5)
    except: pass

# Play amplitudes at 30fps
frame_dur = 1.0 / 30
for amp in amps:
    send_amp(amp)
    time.sleep(frame_dur)

# Close mouth
send_amp(0)
time.sleep(0.3)
" 2>/dev/null
  else
    # Normal mode: just tell browser to play audio, wait for duration
    local duration
    duration=$(curl -sfI "$TTS_URL/tts?text=$encoded" 2>/dev/null | grep -i x-audio-duration | tr -d '\r' | awk '{print $2}')
    duration=${duration:-2}
    post "{\"action\":\"avatar_say\",\"text\":\"$escaped\"}"
    python3 -c "import time; time.sleep($duration + 0.3)"
  fi
}

case "${1:-help}" in
  show)  post '{"action":"avatar_show"}' ;;
  hide)  post '{"action":"avatar_hide"}' ;;
  say)
    shift
    SAVE_DIR=""
    if [ "$1" = "--save" ]; then shift; SAVE_DIR="$1"; mkdir -p "$SAVE_DIR"; shift; fi
    TEXT="$*"
    [ -z "$TEXT" ] && { echo "Usage: avatar say [--save DIR] \"text\"" >&2; exit 1; }
    avatar_say "$TEXT" "$SAVE_DIR"
    ;;
  demo)
    post '{"action":"avatar_show"}'
    sleep 1
    for phrase in \
      "Hi! I am Herb, the Adom avatar." \
      "I can narrate demos and walkthroughs for you." \
      "Just tell your agent to use the avatar skill!" \
      "See you around!"; do
      avatar_say "$phrase"
    done
    sleep 1
    post '{"action":"avatar_hide"}'
    ;;
  help|--help|-h)
    echo "avatar — 3D talking avatar overlay"
    echo "  show / hide / say \"text\" / say --save DIR \"text\" / demo"
    ;;
  *)  echo "Unknown: $1" >&2; exit 1 ;;
esac
