#!/usr/bin/env bash
# Quickstart: place a simulated call in test mode and read its results.
# Requires bash, curl and jq. Test mode never dials a real phone and never charges anything.
#
#   export RELATIONSAI_API_KEY="rai_test_..."
#   export RELATIONSAI_API_BASE="https://voice-api.relationsai.com/v1"   # optional, this is the default
#   bash quickstart.sh
#
# Optional: RELATIONSAI_AGENT_ID=agent_... to use one of your own agents instead of the Sample agent.
set -euo pipefail

BASE="${RELATIONSAI_API_BASE:-https://voice-api.relationsai.com/v1}"
BASE="${BASE%/}"

# This script only ever runs in test mode.
if [[ "${RELATIONSAI_API_KEY:-}" != rai_test_* ]]; then
  echo "Set RELATIONSAI_API_KEY to a test key (rai_test_...). This quickstart never uses a live key." >&2
  exit 1
fi

BODY_FILE="$(mktemp)"
trap 'rm -f "$BODY_FILE"' EXIT

# api METHOD PATH [JSON_BODY]: prints the response body, fails on an error status.
api() {
  local method="$1" path="$2" body="${3:-}" status
  local args=(-sS -X "$method" "$BASE$path" -H "Authorization: Bearer $RELATIONSAI_API_KEY"
    --max-time 30 -o "$BODY_FILE" -w '%{http_code}')
  if [[ -n "$body" ]]; then args+=(-H "Content-Type: application/json" --data "$body"); fi
  status="$(curl "${args[@]}")"
  if [[ "$status" -ge 400 ]]; then
    jq -r --arg s "$status" --arg r "$method $path" \
      '"\($r) failed with \($s) \(.error.code) (request \(.error.request_id)): \(.error.message)"' "$BODY_FILE" >&2
    return 1
  fi
  cat "$BODY_FILE"
}

# 1. Check the key: which workspace, which mode, which scopes.
workspace="$(api GET /workspace)"
if [[ "$(jq -r '.livemode' <<<"$workspace")" != "false" ]]; then
  echo "Expected a test-mode key (livemode false)." >&2
  exit 1
fi
jq -r '"Workspace: \(.name) (test mode), key \"\(.api_key.name)\""' <<<"$workspace"
if ! jq -e '.api_key.scopes | index("calls:write")' >/dev/null <<<"$workspace"; then
  echo "This key cannot place calls. Create a test key with the calls:write scope." >&2
  exit 1
fi

# 2. Find an agent: the one you chose, or the built-in Sample agent.
agent_id="" cursor=""
while :; do
  path="/agents?limit=100"
  if [[ -n "$cursor" ]]; then path="$path&cursor=$cursor"; fi
  page="$(api GET "$path")"
  agent_id="$(jq -r --arg want "${RELATIONSAI_AGENT_ID:-}" \
    'first(.data[] | select(if $want != "" then .id == $want else .sample end) | .id) // empty' <<<"$page")"
  cursor="$(jq -r 'if .has_more then .next_cursor else empty end' <<<"$page")"
  if [[ -n "$agent_id" || -z "$cursor" ]]; then break; fi
done
if [[ -z "$agent_id" ]]; then
  echo "No matching agent found. Check the agent id." >&2
  exit 1
fi
echo "Agent: $agent_id"

# 3. Check that the agent can place calls right now.
readiness="$(api GET "/agents/$agent_id/readiness")"
if [[ "$(jq -r '.ready' <<<"$readiness")" != "true" ]]; then
  jq -r '"The agent is not ready: " + ([.reasons[] | "\(.code): \(.message)"] | join("; "))' <<<"$readiness" >&2
  exit 1
fi

# 4. Place a simulated call. +12025550100 answers and completes the conversation.
payload="$(jq -n --arg agent "$agent_id" '{agent_id: $agent, to: "+12025550100", metadata: {source: "quickstart"}}')"
# Sent once: if it times out, list your calls (GET /calls?to=...) before sending it again.
call="$(api POST /calls "$payload")"
call_id="$(jq -r '.id' <<<"$call")"
echo "Call $call_id accepted: $(jq -r '.status' <<<"$call")"

# 5. Poll until the call is settled (about 30 seconds in test mode). In production, prefer webhooks.
deadline=$(( $(date +%s) + 120 ))
status="$(jq -r '.status' <<<"$call")"
while [[ "$(jq -r '.settled' <<<"$call")" != "true" ]]; do
  if (( $(date +%s) > deadline )); then echo "Call $call_id did not settle within 2 minutes." >&2; exit 1; fi
  sleep 3
  call="$(api GET "/calls/$call_id")"
  if [[ "$(jq -r '.status' <<<"$call")" != "$status" ]]; then
    status="$(jq -r '.status' <<<"$call")"
    echo "Status: $status"
  fi
done
jq -r '"Settled: outcome \(.outcome), \(.duration_seconds) s, cost \(.cost.amount) \(.cost.currency)"' <<<"$call"

# 6. Read the results.
api GET "/calls/$call_id/transcript" |
  jq -r '"Transcript (\(.state), \(.turns | length) turns):", (.turns[:4][] | "  \(.speaker): \(.text)")'

# The recording url is a short-lived credential: use it, but do not log or store it.
api GET "/calls/$call_id/recording" |
  jq -r '"Recording: \(.state), \(.content_type // "no audio"), link expires \(.expires_at // "n/a")"'

api GET "/calls/$call_id/analysis" |
  jq -r '"Analysis: \(.state), goal met: \(.goal_met)",
         (if .summary.text then "  Summary: \(.summary.text)" else empty end),
         (.extracted_fields[] | "  \(.name) = \(.value | tojson)")'

echo "Done. Next: receive call.ended and call.settled by webhook instead of polling."
