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

# elevenlabs-tts.sh
#
# Usage:
#   ./elevenlabs-tts.sh "Hello world"            # writes output.mp3
#   echo "Hello world" | ./elevenlabs-tts.sh     # reads from stdin
#   ./elevenlabs-tts.sh -o hello.mp3 "Hi"        # custom output file
#   ./elevenlabs-tts.sh -v pNInz6obpgDQGcFmaJgB "Hi"  # Adam voice
#
# Environment:
#   ELEVENLABS_API_KEY  (required)
#   ELEVENLABS_VOICE_ID (optional default voice id)
#
# Default voice is Rachel (voice id: 21m00Tcm4TlvDq8ikWAM).
# Default model is eleven_multilingual_v2 and output format is mp3_44100_128.

VOICE_ID_DEFAULT="21m00Tcm4TlvDq8ikWAM"  # Rachel
MODEL_ID="eleven_multilingual_v2"
OUTPUT_FORMAT="mp3_44100_128"
OUT_FILE="output.mp3"

VOICE_ID="${ELEVENLABS_VOICE_ID:-$VOICE_ID_DEFAULT}"

usage() {
  echo "Usage: $0 [-o output.mp3] [-v voice_id] [text...]" >&2
  exit 1
}

while getopts ":o:v:h" opt; do
  case "$opt" in
    o) OUT_FILE="$OPTARG" ;;
    v) VOICE_ID="$OPTARG" ;;
    h) usage ;;
    *) usage ;;
  esac
done
shift $((OPTIND - 1))

if [[ -z "${ELEVENLABS_API_KEY:-}" ]]; then
  echo "Error: ELEVENLABS_API_KEY is not set." >&2
  exit 1
fi

# Read text from args or stdin
if [[ "$#" -gt 0 ]]; then
  TEXT="$*"
else
  if ! read -r -d '' TEXT; then
    # read returns non-zero on EOF; that's fine as long as we got input
    true
  fi
  if [[ -z "${TEXT:-}" ]]; then
    echo "Error: No input text provided." >&2
    usage
  fi
fi

# Build JSON payload safely
PAYLOAD=$(TTS_TEXT="$TEXT" TTS_MODEL_ID="$MODEL_ID" TTS_OUTPUT_FORMAT="$OUTPUT_FORMAT" python3 - <<'PY'
import json
import os
text = os.environ["TTS_TEXT"]
model_id = os.environ["TTS_MODEL_ID"]
output_format = os.environ["TTS_OUTPUT_FORMAT"]
print(json.dumps({
    "text": text,
    "model_id": model_id,
    "output_format": output_format,
}))
PY
)

curl -sS -X POST "https://api.elevenlabs.io/v1/text-to-speech/${VOICE_ID}" \
  -H "Content-Type: application/json" \
  -H "xi-api-key: ${ELEVENLABS_API_KEY}" \
  -d "${PAYLOAD}" \
  --output "${OUT_FILE}"

echo "Wrote ${OUT_FILE}"