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

VERSION="1.0.0"
APP_VERSION="2026.08.27.1"
NODE_BIN="${NODE_BIN:-/opt/cpanel/ea-nodejs22/bin/node}"
NPM_BIN="${NPM_BIN:-/opt/cpanel/ea-nodejs22/bin/npm}"
ROOT="$(pwd)"
LOG="$ROOT/yourstories-install.log"

exec > >(tee -a "$LOG") 2>&1

fail(){ echo; echo "INSTALL FAILED: $*"; echo "Log: $LOG"; exit 1; }
trap 'fail "Command failed at line $LINENO."' ERR

printf '\nYourStories.life Terminal Installer %s\n' "$VERSION"
printf 'Application: %s\n' "$APP_VERSION"
printf 'Folder: %s\n\n' "$ROOT"

[[ -f "$ROOT/payload.zip" ]] || fail "payload.zip is missing. Upload and extract the complete Terminal Installer ZIP first."
command -v unzip >/dev/null 2>&1 || fail "The unzip command is not available on this server."
[[ -x "$NODE_BIN" ]] || fail "Node.js 22 not found at $NODE_BIN. Ask your host to enable ea-nodejs22."
[[ -x "$NPM_BIN" ]] || fail "npm not found at $NPM_BIN. Ask your host to enable ea-nodejs22."

echo "✓ Node: $($NODE_BIN -v)"
echo "✓ npm:  $($NPM_BIN -v)"

read_default(){ local __var=$1 __label=$2 __default=$3 __value; read -r -p "$__label [$__default]: " __value; printf -v "$__var" '%s' "${__value:-$__default}"; }
read_required(){ local __var=$1 __label=$2 __value=""; while [[ -z "$__value" ]]; do read -r -p "$__label: " __value; done; printf -v "$__var" '%s' "$__value"; }
read_secret(){ local __var=$1 __label=$2 __value=""; while [[ -z "$__value" ]]; do read -r -s -p "$__label: " __value; echo; done; printf -v "$__var" '%s' "$__value"; }
secret32(){ if command -v openssl >/dev/null 2>&1; then openssl rand -hex 32; else "$NODE_BIN" -e 'console.log(require("crypto").randomBytes(32).toString("hex"))'; fi; }
urlencode(){ "$NODE_BIN" -e 'process.stdout.write(encodeURIComponent(process.argv[1]))' "$1"; }

read_default APP_URL "Website URL" "https://staging.yourstories.life"
read_required DB_NAME "MySQL database name"
read_required DB_USER "MySQL database user"
read_secret DB_PASS "MySQL database password"
read_default ADMIN_EMAIL "Administrator email" "admin@yourstories.life"
read_default ADMIN_NAME "Administrator name" "Platform Administrator"

echo
printf 'Email settings (used for the six-digit login code)\n'
read_default SMTP_HOST "SMTP host" "mail.yourstories.life"
read_default SMTP_PORT "SMTP port" "465"
read_default SMTP_USER "SMTP username" "noreply@yourstories.life"
read_secret SMTP_PASS "SMTP password"
read_default SMTP_FROM "From address" "YourStories.life <noreply@yourstories.life>"

TURNSTILE_SITE=""; TURNSTILE_SECRET=""; TURNSTILE_REQUIRED="false"
read -r -p "Configure Cloudflare Turnstile now? [y/N]: " TURN_ANS
if [[ "${TURN_ANS,,}" == "y" || "${TURN_ANS,,}" == "yes" ]]; then
  read_required TURNSTILE_SITE "Turnstile site key"
  read_secret TURNSTILE_SECRET "Turnstile secret key"
  TURNSTILE_REQUIRED="true"
fi

R2_ACCOUNT=""; R2_KEY=""; R2_SECRET=""; R2_PRIVATE="yourstories-stage-private"; R2_PUBLIC="yourstories-stage-public"; R2_PUBLIC_URL="https://media-staging.yourstories.life"
read -r -p "Configure Cloudflare R2 now? [y/N]: " R2_ANS
if [[ "${R2_ANS,,}" == "y" || "${R2_ANS,,}" == "yes" ]]; then
  read_required R2_ACCOUNT "R2 Account ID"
  read_required R2_KEY "R2 Access Key ID"
  read_secret R2_SECRET "R2 Secret Access Key"
  read_default R2_PRIVATE "Private bucket" "$R2_PRIVATE"
  read_default R2_PUBLIC "Public bucket" "$R2_PUBLIC"
  read_default R2_PUBLIC_URL "Public media URL" "$R2_PUBLIC_URL"
fi

DB_USER_ENC="$(urlencode "$DB_USER")"
DB_PASS_ENC="$(urlencode "$DB_PASS")"
DATABASE_URL="mysql://${DB_USER_ENC}:${DB_PASS_ENC}@localhost/${DB_NAME}"

AUTH_SECRET="$(secret32)"
OTP_SECRET="$(secret32)"
QR_SECRET="$(secret32)"
IP_SECRET="$(secret32)"

printf '\nInstalling application files...\n'
TMP="$(mktemp -d "$ROOT/.ys-install.XXXXXX")"
unzip -q "$ROOT/payload.zip" -d "$TMP"
[[ -d "$TMP/payload" ]] || fail "payload.zip does not contain the expected payload directory."

# Keep domain-level files that cPanel/AutoSSL may already use. Copy application files over them only when intended.
shopt -s dotglob nullglob
for item in "$TMP/payload"/*; do
  base="$(basename "$item")"
  case "$base" in
    .htaccess|.user.ini|.well-known) continue ;;
  esac
  rm -rf "$ROOT/$base"
  cp -a "$item" "$ROOT/$base"
done
shopt -u dotglob nullglob
rm -rf "$TMP"

cat > "$ROOT/.env" <<EOF
NODE_ENV=production
APP_URL=$APP_URL
APP_HOST=0.0.0.0
ALLOWED_ORIGINS=$APP_URL
APP_VERSION=$APP_VERSION
DATABASE_URL=$DATABASE_URL
AUTH_SECRET=$AUTH_SECRET
OTP_SECRET=$OTP_SECRET
QR_ACTIVATION_SECRET=$QR_SECRET
IP_HASH_SECRET=$IP_SECRET
SESSION_DAYS=30
OTP_MINUTES=10
CLAIM_SESSION_MINUTES=45
CLAIM_RESERVATION_MINUTES=30
ALLOW_CONSOLE_OTP=false
SMTP_HOST=$SMTP_HOST
SMTP_PORT=$SMTP_PORT
SMTP_SECURE=true
SMTP_USER=$SMTP_USER
SMTP_PASSWORD=$SMTP_PASS
SMTP_FROM=$SMTP_FROM
NEXT_PUBLIC_TURNSTILE_SITE_KEY=$TURNSTILE_SITE
TURNSTILE_SECRET_KEY=$TURNSTILE_SECRET
TURNSTILE_REQUIRED=$TURNSTILE_REQUIRED
R2_ACCOUNT_ID=$R2_ACCOUNT
R2_ACCESS_KEY_ID=$R2_KEY
R2_SECRET_ACCESS_KEY=$R2_SECRET
R2_PRIVATE_BUCKET=$R2_PRIVATE
R2_PUBLIC_BUCKET=$R2_PUBLIC
R2_PUBLIC_BASE_URL=$R2_PUBLIC_URL
ADMIN_EMAIL=$ADMIN_EMAIL
ADMIN_NAME=$ADMIN_NAME
EOF
chmod 600 "$ROOT/.env"

mkdir -p "$ROOT/tmp" "$ROOT/logs"

echo
printf 'Installing Node dependencies. This may take a few minutes...\n'
if [[ -f "$ROOT/package-lock.json" ]]; then
  "$NPM_BIN" ci --omit=dev --no-audit --no-fund
else
  "$NPM_BIN" install --omit=dev --no-audit --no-fund
fi

echo
"$NODE_BIN" scripts/check-env.mjs

echo
printf 'Building YourStories.life...\n'
"$NPM_BIN" run build

echo
printf 'Creating/updating database tables...\n'
"$NODE_BIN" scripts/migrate.mjs

echo
printf 'Creating/updating administrator...\n'
"$NODE_BIN" scripts/seed-admin.mjs

touch "$ROOT/tmp/restart.txt"

cat > "$ROOT/INSTALL-COMPLETE.txt" <<EOF
YourStories.life $APP_VERSION installed on $(date -u '+%Y-%m-%d %H:%M:%S UTC')
URL: $APP_URL
Admin: $ADMIN_EMAIL
Folder: $ROOT
EOF

printf '\n============================================================\n'
printf 'YOURSTORIES.LIFE APPLICATION INSTALLATION COMPLETE\n'
printf '============================================================\n'
printf 'Website: %s\n' "$APP_URL"
printf 'Admin email: %s\n' "$ADMIN_EMAIL"
printf '\nIMPORTANT: If the website still shows a PHP/404/500 page, register this folder once in cPanel > Application Manager:\n'
printf '  Domain: staging.yourstories.life\n'
printf '  Application path: %s\n' "${ROOT#$HOME/}"
printf '  Base URL: /\n'
printf '  Environment: Production\n'
printf '  Startup file: app.js\n'
printf '  Node.js: ea-nodejs22\n'
printf '\nThen run: touch %s/tmp/restart.txt\n' "$ROOT"
printf '\nInstall log: %s\n' "$LOG"
