#!/usr/bin/env bash
#
# release-app.sh — one-command release of the BUNDLED Capacitor app.
#
# Does the whole cycle:
#   1. bump the version (android/app/build.gradle + android/update-files/version.json)
#   2. npm run build:app        (rebuild the mobile-only static SPA → .output/public)
#   3. npm run cap:sync:app     (copy the bundle into android/)
#   4. gradle assembleDebug     (build the APK) + stage it into android/update-files/
#   5. publish — MOBILE_PUBLISH is a comma list of targets, DEFAULT "erp":
#        erp     scripts/publish-mobile-update.sh  → ERP server-side channel (app.logship.de,
#                data/mobile-releases/, no ERP deploy needed) — the channel all devices use
#        landing scripts/stage-mobile-update.sh    → ../logship/logyou-landing public/logship
#                (legacy channel, only for update checks without a session; commit + push = deploy)
#        sftp    scripts/upload-mobile-update.sh   → SFTP web root (Blut24)
#
# Interactive: run without arguments and it asks for everything — version name (Enter = auto
# bump), release notes, publish target (Enter = ERP only) and a final confirmation. Every answer
# can be pre-set to run it non-interactively:
#
# Usage:
#   scripts/release-app.sh                 # interactive (defaults: auto-bump, ERP channel only)
#   scripts/release-app.sh 1.1.0           # explicit versionName (skips the version prompt)
#   scripts/release-app.sh --no-upload     # build + stage only, don't publish
#   scripts/release-app.sh --push          # when "landing" is a target: also git push the website repo
#   scripts/release-app.sh --yes           # no prompts at all (uses defaults / env values)
#   RELEASE_NOTES="..." scripts/release-app.sh          # skip the notes prompt
#   MOBILE_PUBLISH=erp,landing scripts/release-app.sh   # skip the target prompt
#
# versionCode is always auto-incremented by 1. versionName must strictly increase or the in-app
# updater won't offer the release.
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$REPO_ROOT"

GRADLE="android/app/build.gradle"
VERSION_JSON="android/update-files/version.json"
APK_BUILT="android/app/build/outputs/apk/debug/app-debug.apk"
APK_STAGED="android/update-files/logship-mobile.apk"

bold() { printf '\033[1m%s\033[0m\n' "$*"; }
err()  { printf '\033[31mERROR:\033[0m %s\n' "$*" >&2; }
ok()   { printf '\033[32m✔\033[0m %s\n' "$*"; }

# --------------------------------------------------------------------------
# Args
# --------------------------------------------------------------------------
NO_UPLOAD=0
PUSH_SITE=0
ASSUME_YES=0
NEW_NAME_ARG=""
for a in "$@"; do
  case "$a" in
    --no-upload) NO_UPLOAD=1 ;;
    --push) PUSH_SITE=1 ;;
    --yes|-y) ASSUME_YES=1 ;;
    -h|--help) sed -n '3,22p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    --*) err "unknown option: $a"; exit 1 ;;
    *) NEW_NAME_ARG="$a" ;;
  esac
done

# --------------------------------------------------------------------------
# Current version
# --------------------------------------------------------------------------
CUR_CODE="$(grep -E 'versionCode +[0-9]+' "$GRADLE" | head -1 | grep -oE '[0-9]+' | head -1)"
CUR_NAME="$(grep -E 'versionName +"[^"]*"' "$GRADLE" | head -1 | sed -E 's/.*versionName +"([^"]*)".*/\1/')"
if [ -z "$CUR_CODE" ] || [ -z "$CUR_NAME" ]; then
  err "could not read current versionCode/versionName from $GRADLE"; exit 1
fi

NEW_CODE=$(( CUR_CODE + 1 ))
# auto-increment the last dotted numeric segment (bash 3.2 safe — no negative array index)
IFS='.' read -r -a PARTS <<< "$CUR_NAME"
last=$(( ${#PARTS[@]} - 1 ))
AUTO_NAME=""
if [[ "${PARTS[$last]}" =~ ^[0-9]+$ ]]; then
  PARTS[$last]=$(( ${PARTS[$last]} + 1 ))
  AUTO_NAME="$(IFS='.'; echo "${PARTS[*]}")"
fi

echo
bold "Current app version: $CUR_NAME (code $CUR_CODE)"
if [ -n "$NEW_NAME_ARG" ]; then
  NEW_NAME="$NEW_NAME_ARG"
elif [ "$ASSUME_YES" = "1" ]; then
  NEW_NAME="$AUTO_NAME"
else
  read -rp "New versionName [${AUTO_NAME:-required}]: " NEW_NAME
  NEW_NAME="${NEW_NAME:-$AUTO_NAME}"
fi
if [ -z "$NEW_NAME" ]; then err "versionName '$CUR_NAME' doesn't end in a number — enter an explicit version"; exit 1; fi
if ! [[ "$NEW_NAME" =~ ^[0-9]+(\.[0-9]+){1,3}$ ]]; then err "invalid versionName '$NEW_NAME' (expected e.g. 1.0.42)"; exit 1; fi
if [ "$NEW_NAME" = "$CUR_NAME" ]; then err "versionName must increase (still $CUR_NAME) — the in-app updater compares versionName"; exit 1; fi

bold "Release  $CUR_NAME (code $CUR_CODE)  ->  $NEW_NAME (code $NEW_CODE)"

# --------------------------------------------------------------------------
# Release notes
# --------------------------------------------------------------------------
RELEASE_NOTES="${RELEASE_NOTES:-}"
if [ -z "$RELEASE_NOTES" ] && [ "$ASSUME_YES" != "1" ]; then
  read -rp "Release notes (DE) [Verbesserungen und Fehlerbehebungen.]: " RELEASE_NOTES
fi
RELEASE_NOTES="${RELEASE_NOTES:-Verbesserungen und Fehlerbehebungen.}"

# --------------------------------------------------------------------------
# Publish target (default: ERP channel only)
# --------------------------------------------------------------------------
MOBILE_PUBLISH="${MOBILE_PUBLISH:-}"
if [ "$NO_UPLOAD" = "1" ]; then
  MOBILE_PUBLISH=""
elif [ -z "$MOBILE_PUBLISH" ]; then
  if [ "$ASSUME_YES" = "1" ]; then
    MOBILE_PUBLISH="erp"
  else
    echo
    echo "Publish to:"
    echo "  1) ERP channel only (app.logship.de — what all devices use)   [default]"
    echo "  2) ERP channel + logyou.de website repo (legacy channel)"
    echo "  3) SFTP web root (Blut24 / upload-mobile-update.sh)"
    echo "  4) nothing — build + stage only"
    read -rp "Choice [1]: " choice
    case "${choice:-1}" in
      1) MOBILE_PUBLISH="erp" ;;
      2) MOBILE_PUBLISH="erp,landing" ;;
      3) MOBILE_PUBLISH="sftp" ;;
      4) MOBILE_PUBLISH=""; NO_UPLOAD=1 ;;
      *) err "invalid choice"; exit 1 ;;
    esac
    if [[ ",$MOBILE_PUBLISH," == *",landing,"* ]] && [ "$PUSH_SITE" != "1" ]; then
      read -rp "Also git push the website repo (= deploy logyou.de)? [y/N] " p
      case "$p" in y|Y) PUSH_SITE=1 ;; esac
    fi
  fi
fi

echo
bold "Summary"
printf '  version : %s (code %s)\n' "$NEW_NAME" "$NEW_CODE"
printf '  notes   : %s\n' "$RELEASE_NOTES"
printf '  publish : %s%s\n' "${MOBILE_PUBLISH:-none (build + stage only)}" "$( [ "$PUSH_SITE" = "1" ] && printf ' (+ push website repo)' )"
if [ "$ASSUME_YES" != "1" ]; then
  read -rp "Build and publish this release? [y/N] " go
  case "$go" in y|Y) ;; *) echo "Aborted."; exit 0;; esac
fi

# --------------------------------------------------------------------------
# 1. Bump versions
# --------------------------------------------------------------------------
sed -E "s/versionCode +[0-9]+/versionCode $NEW_CODE/; s/versionName +\"[^\"]*\"/versionName \"$NEW_NAME\"/" \
  "$GRADLE" > "$GRADLE.tmp" && mv "$GRADLE.tmp" "$GRADLE"
ok "build.gradle → versionName $NEW_NAME / versionCode $NEW_CODE"

REL_DATE="$(date +%Y-%m-%d)"
MIN_REQ="$(grep -oE '"minRequiredVersion"[^,}]*' "$VERSION_JSON" 2>/dev/null | sed -E 's/.*: *"([^"]*)".*/\1/')"
MIN_REQ="${MIN_REQ:-1.0.0}"
# JSON-escape the notes (backslash + double-quote)
ESC_NOTES="$(printf '%s' "$RELEASE_NOTES" | sed 's/\\/\\\\/g; s/"/\\"/g')"
cat > "$VERSION_JSON" <<EOF
{
  "versionName": "$NEW_NAME",
  "versionCode": $NEW_CODE,
  "apkUrl": "logship-mobile.apk",
  "releaseNotes": "$ESC_NOTES",
  "releaseDate": "$REL_DATE",
  "minRequiredVersion": "$MIN_REQ"
}
EOF
ok "version.json → versionName $NEW_NAME / versionCode $NEW_CODE"

# --------------------------------------------------------------------------
# 2. Build the static SPA + 3. sync native
# --------------------------------------------------------------------------
echo; bold "Building mobile SPA (npm run build:app)…"
npm run build:app
echo; bold "Syncing native project (npm run cap:sync:app)…"
npm run cap:sync:app

# --------------------------------------------------------------------------
# 4. Build the APK + stage
# --------------------------------------------------------------------------
export JAVA_HOME="$(/usr/libexec/java_home -v 21 2>/dev/null || echo /Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home)"
echo; bold "Building APK (gradle assembleDebug)…"
( cd android && ./gradlew assembleDebug --console=plain )

if [ ! -f "$APK_BUILT" ]; then err "APK not found at $APK_BUILT"; exit 1; fi
cp "$APK_BUILT" "$APK_STAGED"
ok "staged $APK_STAGED ($(du -h "$APK_STAGED" | cut -f1))"

# Quick sanity: APK version should match version.json (the upload script re-checks this too).
AAPT="$(ls -1 "${ANDROID_HOME:-$HOME/Library/Android/sdk}"/build-tools/*/aapt 2>/dev/null | sort -V | tail -1 || true)"
if [ -n "$AAPT" ]; then
  APK_VER="$("$AAPT" dump badging "$APK_STAGED" 2>/dev/null | grep -oE "versionCode='[0-9]+' versionName='[^']+'")"
  echo "  APK: $APK_VER"
fi

# --------------------------------------------------------------------------
# 5. Publish
# --------------------------------------------------------------------------
if [ "$NO_UPLOAD" = "1" ] || [ -z "$MOBILE_PUBLISH" ]; then
  echo; ok "Build complete (upload skipped: --no-upload)."
  echo "  Publish later with:  scripts/publish-mobile-update.sh   (ERP channel)"
  echo "                       scripts/stage-mobile-update.sh     (logyou.de legacy channel)"
else
  IFS=',' read -r -a PUBLISH_TARGETS <<< "$MOBILE_PUBLISH"
  for target in "${PUBLISH_TARGETS[@]}"; do
    case "$(printf '%s' "$target" | tr -d ' ')" in
      erp)
        echo; bold "Publishing into the ERP release channel…"
        "$SCRIPT_DIR/publish-mobile-update.sh" ;;
      landing)
        echo; bold "Publishing into the logyou.de website repo (legacy channel)…"
        if [ "$PUSH_SITE" = "1" ]; then "$SCRIPT_DIR/stage-mobile-update.sh" --push; else "$SCRIPT_DIR/stage-mobile-update.sh" --commit; fi ;;
      sftp)
        echo; bold "Publishing via SFTP…"
        "$SCRIPT_DIR/upload-mobile-update.sh" ;;
      "") ;;
      *) err "unknown MOBILE_PUBLISH target: $target"; exit 1 ;;
    esac
  done
fi

echo
ok "Done — released $NEW_NAME (code $NEW_CODE)."
echo "  ↪ Commit the version bump:  git add $GRADLE $VERSION_JSON && git commit -m \"release app $NEW_NAME\""
