#!/usr/bin/env bash
# openai-image.sh — generate or edit images via OpenAI gpt-image-1.5
#
# Usage:
#   ./openai-image.sh --prompt "..." --output path.png [options]
#
# Options:
#   --prompt "..."              (required) prompt text
#   --output path.png           (required) output file path
#   --quality low|medium|high   default: high
#   --size 1024x1024|1024x1536|1536x1024   default: 1024x1024
#   --background opaque|transparent        default: opaque
#   --output-format png|jpeg|webp          default: png
#   --moderation auto|low                  default: auto
#   --n N                                  default: 1 (additional images saved as path-2.png, path-3.png, ...)
#   --ref path.png                         (repeatable, up to 16; first 5 preserved at high fidelity).
#                                          Presence of any --ref switches to /v1/images/edits.
#   --input-fidelity low|high              default: high (only applies in edit mode)
#   --model gpt-image-1.5                  default: gpt-image-1.5
#
# Env:
#   OPENAI_IMAGE_API_KEY (required)        Get from ~/.claude/projects/-Users-shaharshavit/memory/api-keys.md
#                                          → "OpenAI (image generation)" section.

set -euo pipefail

PROMPT=""
OUTPUT=""
QUALITY="high"
SIZE="1024x1024"
BACKGROUND="opaque"
OUTPUT_FORMAT="png"
MODERATION="auto"
N=1
INPUT_FIDELITY="high"
MODEL="gpt-image-1.5"
REFS=()

while [[ $# -gt 0 ]]; do
  case "$1" in
    --prompt)          PROMPT="$2"; shift 2 ;;
    --output)          OUTPUT="$2"; shift 2 ;;
    --quality)         QUALITY="$2"; shift 2 ;;
    --size)            SIZE="$2"; shift 2 ;;
    --background)      BACKGROUND="$2"; shift 2 ;;
    --output-format)   OUTPUT_FORMAT="$2"; shift 2 ;;
    --moderation)      MODERATION="$2"; shift 2 ;;
    --n)               N="$2"; shift 2 ;;
    --ref)             REFS+=("$2"); shift 2 ;;
    --input-fidelity)  INPUT_FIDELITY="$2"; shift 2 ;;
    --model)           MODEL="$2"; shift 2 ;;
    -h|--help)         sed -n '1,30p' "$0"; exit 0 ;;
    *) echo "Unknown arg: $1" >&2; exit 1 ;;
  esac
done

[[ -z "$PROMPT" ]] && { echo "Error: --prompt is required" >&2; exit 1; }
[[ -z "$OUTPUT" ]] && { echo "Error: --output is required" >&2; exit 1; }
: "${OPENAI_IMAGE_API_KEY:?Set OPENAI_IMAGE_API_KEY (see ~/.claude/projects/-Users-shaharshavit/memory/api-keys.md → 'OpenAI (image generation)')}"

# Make sure output dir exists
mkdir -p "$(dirname "$OUTPUT")"

# Pick endpoint
if [[ ${#REFS[@]} -eq 0 ]]; then
  ENDPOINT="https://api.openai.com/v1/images/generations"
  BODY=$(jq -n \
    --arg model "$MODEL" \
    --arg prompt "$PROMPT" \
    --arg quality "$QUALITY" \
    --arg size "$SIZE" \
    --arg background "$BACKGROUND" \
    --arg output_format "$OUTPUT_FORMAT" \
    --arg moderation "$MODERATION" \
    --argjson n "$N" \
    '{model:$model, prompt:$prompt, quality:$quality, size:$size, background:$background, output_format:$output_format, moderation:$moderation, n:$n}')

  echo "▸ POST $ENDPOINT (generate, n=$N, quality=$QUALITY, size=$SIZE)" >&2
  RESP=$(curl -sS -X POST "$ENDPOINT" \
    -H "Authorization: Bearer $OPENAI_IMAGE_API_KEY" \
    -H "Content-Type: application/json" \
    -d "$BODY")
else
  ENDPOINT="https://api.openai.com/v1/images/edits"
  if [[ ${#REFS[@]} -gt 16 ]]; then
    echo "Error: max 16 reference images" >&2; exit 1
  fi
  echo "▸ POST $ENDPOINT (edit, ${#REFS[@]} ref(s), quality=$QUALITY, size=$SIZE, input_fidelity=$INPUT_FIDELITY)" >&2

  CURL_ARGS=(
    -sS -X POST "$ENDPOINT"
    -H "Authorization: Bearer $OPENAI_IMAGE_API_KEY"
    -F "model=$MODEL"
    -F "prompt=$PROMPT"
    -F "quality=$QUALITY"
    -F "size=$SIZE"
    -F "background=$BACKGROUND"
    -F "output_format=$OUTPUT_FORMAT"
    -F "input_fidelity=$INPUT_FIDELITY"
    -F "n=$N"
  )
  if [[ ${#REFS[@]} -gt 0 ]]; then
    for ref in "${REFS[@]}"; do
      [[ -f "$ref" ]] || { echo "Error: ref not found: $ref" >&2; exit 1; }
      CURL_ARGS+=(-F "image[]=@$ref")
    done
  fi
  RESP=$(curl "${CURL_ARGS[@]}")
fi

# Check for error
if echo "$RESP" | jq -e '.error' >/dev/null 2>&1; then
  echo "API error:" >&2
  echo "$RESP" | jq '.error' >&2
  exit 1
fi

# Save each returned image
COUNT=$(echo "$RESP" | jq '.data | length')
[[ "$COUNT" -eq 0 ]] && { echo "Error: no images in response" >&2; exit 1; }

BASE="${OUTPUT%.*}"
EXT="${OUTPUT##*.}"

for ((i=0; i<COUNT; i++)); do
  if [[ $i -eq 0 ]]; then
    OUT="$OUTPUT"
  else
    OUT="${BASE}-$((i+1)).${EXT}"
  fi
  echo "$RESP" | jq -r ".data[$i].b64_json" | base64 --decode > "$OUT"
  echo "✓ saved: $OUT" >&2
done

# Print first output path on stdout so callers can capture it
echo "$OUTPUT"