#!/usr/bin/env bash
# =====================================================================
# create-master-articles.sh — master ("summary") articles for variation groups of a merchant, through
# the app's own routes: quick-store (name + image, no prices) → products/update (search key, brand,
# category, description) → [id]/flags (isSummary = true, isStocked/isSold/isPurchased = false), so the
# master is a pure structure entity: never stocked, picked, ordered or priced. The variations are linked
# afterwards with set-parent-ids.sh (M_Product.ParentId = master search key).
#
#   ADMIN_USER=demo ADMIN_PASS=… MERCHANT_SHORT=hess MASTERS=/root/demo-setup/hess/masters.json ./create-master-articles.sh
#
# masters.json entry (hess/build-catalog.py): { value, name, group1, group2, classification, description,
# documentNote, imageUrl, variants[] }. Env: BASE [http://127.0.0.1:3001], CLIENT_ID/ROLE_ID/ORG_ID/WH_ID
# (sign-in context, 1000000), IMG_DIR [/root/demo-setup/images/<short>], IMG_DELAY [0.3], LIMIT [0].
# Idempotent: masters are looked up by search key first.
# =====================================================================
set -euo pipefail; export LANG=C.UTF-8
BASE="${BASE:-http://127.0.0.1:3001}"; ADMIN_USER="${ADMIN_USER:?}"; ADMIN_PASS="${ADMIN_PASS:?}"
MERCHANT_SHORT="${MERCHANT_SHORT:?}"; MASTERS="${MASTERS:?}"
CLIENT_ID="${CLIENT_ID:-1000000}"; ROLE_ID="${ROLE_ID:-1000000}"; ORG_ID="${ORG_ID:-1000000}"; WH_ID="${WH_ID:-1000000}"
IMG_DIR="${IMG_DIR:-/root/demo-setup/images/$MERCHANT_SHORT}"; IMG_DELAY="${IMG_DELAY:-0.3}"; LIMIT="${LIMIT:-0}"
JAR="$(mktemp)"; trap 'rm -f "$JAR"' EXIT; mkdir -p "$IMG_DIR"
say() { printf '\n== %s\n' "$*"; }
api() { if [ $# -ge 3 ]; then curl -sS -b "$JAR" -c "$JAR" -X "$1" "$BASE$2" -H 'Content-Type: application/json' -d "$3"; else curl -sS -b "$JAR" -c "$JAR" -X "$1" "$BASE$2"; fi; }
odata() { local enc; enc="$(jq -rn --arg s "\$filter=$2&\$top=${3:-50}" '$s|@uri')"; api GET "/api/filters/$1/$enc"; }
first_id() { jq -r '(.records // .)[0].id // empty'; }
ok() { local st; st="$(echo "$1" | jq -r '.status // 200' 2>/dev/null || echo 500)"; if [ "$st" != 200 ]; then echo "  FAILED: $(echo "$1" | cut -c1-300)" >&2; return 1; fi; }
esc() { printf "%s" "$1" | sed "s/'/''/g"; }

say "sign in as $ADMIN_USER"
login="$(api POST /api/idempiere-auth/login "$(jq -n --arg u "$ADMIN_USER" --arg p "$ADMIN_PASS" '{userName:$u,password:$p,selectRole:true}')")"
echo "$login" | jq -e '.token' >/dev/null || { echo "login failed" >&2; exit 1; }
api POST /api/idempiere-auth/select-role "$(jq -n --argjson c "$CLIENT_ID" --argjson r "$ROLE_ID" --argjson o "$ORG_ID" --argjson w "$WH_ID" '{clientId:$c,roleId:$r,organizationId:$o,warehouseId:$w,language:"de_DE"}')" >/dev/null
api GET /api/idempiere-auth/authenticated | jq -e '.user.id' >/dev/null || { echo "session not authenticated" >&2; exit 1; }
MORG="$(odata ad_org "Value eq '$(esc "$MERCHANT_SHORT")'" | first_id)"; [ -n "$MORG" ] || { echo "org $MERCHANT_SHORT not found" >&2; exit 1; }
echo "  ok — merchant org $MORG"

say "master articles from $MASTERS"
TOTAL="$(jq length "$MASTERS")"; [ "$LIMIT" -gt 0 ] && TOTAL=$(( LIMIT < TOTAL ? LIMIT : TOTAL ))
created=0; existed=0; failed=0
for i in $(seq 0 $((TOTAL-1))); do
  e="$(jq -c ".[$i]" "$MASTERS")"; value="$(echo "$e" | jq -r .value)"; name="$(echo "$e" | jq -r .name)"
  id="$(odata m_product "AD_Org_ID eq $MORG and Value eq '$(esc "$value")'" | first_id)"
  if [ -n "$id" ]; then existed=$((existed+1)); continue; fi
  imgurl="$(echo "$e" | jq -r '.imageUrl // empty')"; imgarg=()
  if [ -n "$imgurl" ]; then
    f="$IMG_DIR/$(printf '%s' "$imgurl" | md5sum | cut -c1-16).img"
    [ -s "$f" ] || { curl -sSL -A "Mozilla/5.0" --max-time 30 -o "$f" "$imgurl" || true; sleep "$IMG_DELAY"; }
    if [ -s "$f" ]; then mime="$(file -b --mime-type "$f" 2>/dev/null || echo image/png)"; case "$mime" in image/*) imgarg=(-F "image=@$f;type=$mime;filename=$value.${mime#image/}");; esac; fi
  fi
  res="$(curl -sS -b "$JAR" -c "$JAR" -X POST "$BASE/api/materials/products/quick-store" -F "name=$name" -F "price=0" -F "organizationId=$MORG" "${imgarg[@]}")"
  if ! ok "$res" 2>/dev/null; then failed=$((failed+1)); echo "  FAILED $value: $(echo "$res" | cut -c1-200)"; continue; fi
  id="$(echo "$res" | jq -r '.id // .product.id')"
  upd="$(api PUT /api/materials/products/update "$(echo "$e" | jq -c --argjson id "$id" --argjson o "$MORG" \
    '{id:$id, organizationId:$o, value:.value, sku:"", upc:"", group1:(.group1 // ""), group2:(.group2 // ""), classification:(.classification // ""), description:(.description // ""), documentNote:(.documentNote // "")}')")"
  ok "$upd" 2>/dev/null || echo "  (details not saved for $value: $(echo "$upd" | cut -c1-120))"
  fl="$(api PUT "/api/materials/products/$id/flags" '{"isSummary":true,"isStocked":false,"isSold":false,"isPurchased":false}')"
  ok "$fl" 2>/dev/null || echo "  (flags not saved for $value: $(echo "$fl" | cut -c1-120))"
  created=$((created+1)); printf '  %3d/%d %s (%s) img=%s variants=%s\n' "$((i+1))" "$TOTAL" "$value" "$id" "$(echo "$res" | jq -r .imageUploaded)" "$(echo "$e" | jq '.variants|length')"
done
say "done — masters created $created / existing $existed / failed $failed (org $MORG)"
