#!/usr/bin/env bash
#
# petav3 — fresh server provisioning script (Ubuntu 24.04 LTS)
# ----------------------------------------------------------------------------
# Brings a bare Ubuntu box to a runnable petav3 state:
#   PHP-FPM 8.4 + extensions, Composer, Node 20, MySQL, Redis, Apache2,
#   the Laravel app, the wa-bridge (Baileys) sidecar, and systemd units for
#   Horizon + the bridge + the Laravel scheduler (petav3-scheduler).
#
# Idempotent: safe to re-run. Each step skips work that is already done.
#
# Usage:
#   sudo APP_DOMAIN=app.example.com \
#        DB_DATABASE=petav3 DB_USERNAME=petav3 DB_PASSWORD='strong-pass' \
#        bash scripts/server-setup.sh
#
# Then verify with:
#   sudo bash scripts/server-verify.sh
#
# Every tunable below can be overridden by exporting it before running.
# ----------------------------------------------------------------------------
set -euo pipefail

# ============================================================================
# Configuration (override via environment variables)
# ============================================================================
PHP_VERSION="${PHP_VERSION:-8.4}"
NODE_MAJOR="${NODE_MAJOR:-20}"

# Where the application lives. If the repo is not already there, set REPO_URL
# to have it cloned. If you ran this script *from inside* a checkout, that
# checkout is used and copied into APP_DIR.
APP_DIR="${APP_DIR:-/var/www/html/peta}"
REPO_URL="${REPO_URL:-https://github.com/property-lab/petav3.git}"
REPO_BRANCH="${REPO_BRANCH:-master}"

# Apache vhost
APP_DOMAIN="${APP_DOMAIN:-_}"            # "_" = default/catch-all vhost
APP_URL="${APP_URL:-http://${APP_DOMAIN}}"

# TLS (Let's Encrypt via certbot --apache). "auto" = obtain a cert only when a
# real APP_DOMAIN and CERTBOT_EMAIL are set; "true" forces it; "false" skips.
# Requires public DNS for APP_DOMAIN pointing at this box and port 80 reachable.
ENABLE_SSL="${ENABLE_SSL:-auto}"
CERTBOT_EMAIL="${CERTBOT_EMAIL:-}"

# Database (created locally on this box)
DB_DATABASE="${DB_DATABASE:-petav3}"
DB_USERNAME="${DB_USERNAME:-petav3}"
DB_PASSWORD="${DB_PASSWORD:-change-me-in-prod}"

# Ownership model: APP_USER owns the code and runs the CLI/workers (the deploy
# user); APP_GROUP is the web-server group so Apache/PHP-FPM (www-data) can read
# the code and write storage/ via group permissions.
APP_USER="${APP_USER:-ubuntu}"
APP_GROUP="${APP_GROUP:-www-data}"
WEB_USER="${WEB_USER:-www-data}"    # PHP-FPM / Apache runtime user

# Build for production by default. Set to "false" for a dev box.
PRODUCTION="${PRODUCTION:-true}"

# ============================================================================
# Output helpers
# ============================================================================
C_RESET='\033[0m'; C_BLUE='\033[1;34m'; C_GREEN='\033[1;32m'; C_YELLOW='\033[1;33m'; C_RED='\033[1;31m'
log()  { echo -e "${C_BLUE}==>${C_RESET} $*"; }
ok()   { echo -e "${C_GREEN}  ✓${C_RESET} $*"; }
warn() { echo -e "${C_YELLOW}  ! ${C_RESET}$*"; }
die()  { echo -e "${C_RED}  ✗ $*${C_RESET}" >&2; exit 1; }

# ============================================================================
# Preconditions
# ============================================================================
[[ "$(id -u)" -eq 0 ]] || die "Run as root (use sudo)."
command -v apt-get >/dev/null || die "This script targets Debian/Ubuntu (apt-get not found)."

. /etc/os-release 2>/dev/null || true
log "Target: ${PRETTY_NAME:-unknown OS} | PHP ${PHP_VERSION} | Node ${NODE_MAJOR} | app at ${APP_DIR}"
[[ "${VERSION_ID:-}" == "24.04" ]] || warn "Tested on Ubuntu 24.04; you have ${VERSION_ID:-unknown}. Continuing."

export DEBIAN_FRONTEND=noninteractive

# ============================================================================
# 1. Base packages + repositories
# ============================================================================
log "Installing base packages and repositories..."
apt-get update -y
apt-get install -y --no-install-recommends \
    software-properties-common ca-certificates curl wget gnupg lsb-release \
    git unzip zip acl
ok "Base packages installed"

# AI Video pipeline OS deps. ffmpeg renders/stitches the clips; fonts-noto-cjk lets
# Chinese captions render — GD (php8.4-gd, installed below) falls back to it for CJK text,
# so without it Chinese captions tofu on Linux even though they render on a macOS dev box.
log "Installing AI Video pipeline packages (ffmpeg, Noto CJK fonts)..."
apt-get install -y --no-install-recommends ffmpeg fonts-noto-cjk
ok "Video pipeline packages installed"

# ondrej/php PPA — provides php8.4-* on Ubuntu
if ! grep -rq "ondrej/php" /etc/apt/sources.list.d/ 2>/dev/null; then
    add-apt-repository -y ppa:ondrej/php
    ok "Added ppa:ondrej/php"
else
    ok "ppa:ondrej/php already present"
fi

# NodeSource — Node 20.x
if ! command -v node >/dev/null || [[ "$(node -v 2>/dev/null | sed 's/v\([0-9]*\).*/\1/')" -lt "$NODE_MAJOR" ]]; then
    curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" | bash -
    apt-get install -y nodejs
    ok "Node $(node -v) installed"
else
    ok "Node $(node -v) already satisfies >= ${NODE_MAJOR}"
fi

apt-get update -y

# ============================================================================
# 2. PHP-FPM 8.4 + extensions
# ============================================================================
log "Installing PHP ${PHP_VERSION} (FPM + CLI) and extensions..."
apt-get install -y \
    "php${PHP_VERSION}" \
    "php${PHP_VERSION}-fpm" \
    "php${PHP_VERSION}-cli" \
    "php${PHP_VERSION}-common" \
    "php${PHP_VERSION}-mysql" \
    "php${PHP_VERSION}-redis" \
    "php${PHP_VERSION}-mbstring" \
    "php${PHP_VERSION}-xml" \
    "php${PHP_VERSION}-curl" \
    "php${PHP_VERSION}-zip" \
    "php${PHP_VERSION}-gd" \
    "php${PHP_VERSION}-bcmath" \
    "php${PHP_VERSION}-intl" \
    "php${PHP_VERSION}-soap" \
    "php${PHP_VERSION}-readline"
ok "PHP $("php${PHP_VERSION}" -r 'echo PHP_VERSION;') installed"

systemctl enable --now "php${PHP_VERSION}-fpm"
ok "php${PHP_VERSION}-fpm enabled and started"

# ============================================================================
# 3. Composer
# ============================================================================
if ! command -v composer >/dev/null; then
    log "Installing Composer..."
    EXPECTED="$(curl -fsSL https://composer.github.io/installer.sig)"
    curl -fsSL https://getcomposer.org/installer -o /tmp/composer-setup.php
    ACTUAL="$("php${PHP_VERSION}" -r "echo hash_file('sha384', '/tmp/composer-setup.php');")"
    [[ "$EXPECTED" == "$ACTUAL" ]] || die "Composer installer checksum mismatch."
    "php${PHP_VERSION}" /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
    rm -f /tmp/composer-setup.php
    ok "Composer $(composer --version 2>/dev/null | awk '{print $3}') installed"
else
    ok "Composer already present ($(composer --version 2>/dev/null | awk '{print $3}'))"
fi

# ============================================================================
# 4. MySQL
# ============================================================================
log "Installing MySQL server..."
apt-get install -y mysql-server
systemctl enable --now mysql
ok "MySQL running"

log "Ensuring database '${DB_DATABASE}' and user '${DB_USERNAME}'..."
mysql --protocol=socket <<SQL
CREATE DATABASE IF NOT EXISTS \`${DB_DATABASE}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '${DB_USERNAME}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
ALTER USER '${DB_USERNAME}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
GRANT ALL PRIVILEGES ON \`${DB_DATABASE}\`.* TO '${DB_USERNAME}'@'localhost';
FLUSH PRIVILEGES;
SQL
ok "Database and user ready"

# ============================================================================
# 5. Redis (queue/cache backend for Horizon)
# ============================================================================
log "Installing Redis server..."
apt-get install -y redis-server
# Run Redis under systemd supervision
sed -i 's/^# *supervised .*/supervised systemd/; s/^supervised .*/supervised systemd/' /etc/redis/redis.conf || true
systemctl enable --now redis-server
ok "Redis running"

# ============================================================================
# 6. Apache2 + PHP-FPM wiring (mod_proxy_fcgi)
# ============================================================================
log "Installing and configuring Apache2..."
apt-get install -y apache2
a2enmod proxy_fcgi setenvif rewrite headers >/dev/null
a2enconf "php${PHP_VERSION}-fpm" >/dev/null 2>&1 || true
# Disable other php*-fpm confs that the ondrej packages may have enabled
for conf in /etc/apache2/conf-enabled/php*-fpm.conf; do
    [[ -e "$conf" ]] || continue
    base="$(basename "$conf" .conf)"
    [[ "$base" == "php${PHP_VERSION}-fpm" ]] || { a2disconf "$base" >/dev/null 2>&1 || true; warn "Disabled stale $base"; }
done
ok "Apache modules + php${PHP_VERSION}-fpm handler enabled"

# ============================================================================
# 7. Application code
# ============================================================================
if [[ -f "${APP_DIR}/artisan" ]]; then
    ok "App already present at ${APP_DIR}"
elif [[ -f "$(dirname "$0")/../artisan" ]]; then
    SRC_DIR="$(cd "$(dirname "$0")/.." && pwd)"
    log "Copying app from local checkout ${SRC_DIR} -> ${APP_DIR}..."
    mkdir -p "${APP_DIR}"
    cp -a "${SRC_DIR}/." "${APP_DIR}/"
    ok "App copied"
else
    log "Cloning ${REPO_URL} (${REPO_BRANCH}) -> ${APP_DIR}..."
    git clone --branch "${REPO_BRANCH}" "${REPO_URL}" "${APP_DIR}"
    ok "App cloned"
fi
cd "${APP_DIR}"

# .env
if [[ ! -f "${APP_DIR}/.env" ]]; then
    cp "${APP_DIR}/.env.example" "${APP_DIR}/.env"
    # Seed the DB + Redis + queue values for a production box
    sed -i \
        -e "s#^APP_ENV=.*#APP_ENV=production#" \
        -e "s#^APP_DEBUG=.*#APP_DEBUG=false#" \
        -e "s#^API_DEBUG=.*#API_DEBUG=false#" \
        -e "s#^APP_URL=.*#APP_URL=${APP_URL}#" \
        -e "s#^DB_DATABASE=.*#DB_DATABASE=${DB_DATABASE}#" \
        -e "s#^DB_USERNAME=.*#DB_USERNAME=${DB_USERNAME}#" \
        -e "s#^DB_PASSWORD=.*#DB_PASSWORD=${DB_PASSWORD}#" \
        -e "s#^QUEUE_DRIVER=.*#QUEUE_DRIVER=redis#" \
        -e "s#^CACHE_DRIVER=.*#CACHE_DRIVER=redis#" \
        -e "s#^SESSION_DRIVER=.*#SESSION_DRIVER=redis#" \
        "${APP_DIR}/.env"
    # Ensure QUEUE_CONNECTION is set (Laravel reads this name)
    grep -q "^QUEUE_CONNECTION=" "${APP_DIR}/.env" || echo "QUEUE_CONNECTION=redis" >> "${APP_DIR}/.env"
    # phpredis is the native client we installed (php8.4-redis)
    grep -q "^REDIS_CLIENT=" "${APP_DIR}/.env" || echo "REDIS_CLIENT=phpredis" >> "${APP_DIR}/.env"
    # Generate a bridge API key if blank
    BRIDGE_KEY="$(openssl rand -hex 24)"
    sed -i "s#^BRIDGE_API_KEY=.*#BRIDGE_API_KEY=${BRIDGE_KEY}#" "${APP_DIR}/.env"
    # Generate the bridge WEBHOOK token too. Laravel now rejects bridge webhooks
    # when this is blank (fail-closed) — an unauthenticated public webhook would
    # otherwise accept forged inbound events. Both the bridge and Laravel read it
    # from this one root .env, so generating it here secures both sides at once.
    BRIDGE_HOOK="wab_hook_$(openssl rand -hex 24)"
    if grep -q "^BRIDGE_WEBHOOK_TOKEN=" "${APP_DIR}/.env"; then
        sed -i "s#^BRIDGE_WEBHOOK_TOKEN=.*#BRIDGE_WEBHOOK_TOKEN=${BRIDGE_HOOK}#" "${APP_DIR}/.env"
    else
        echo "BRIDGE_WEBHOOK_TOKEN=${BRIDGE_HOOK}" >> "${APP_DIR}/.env"
    fi
    ok ".env created and seeded (review it before going live)"
else
    ok ".env already exists (left untouched)"
fi

# Composer install. APP_USER (www-data) usually has nologin, so we install as
# root and fix ownership in the permissions step below.
#
# --no-scripts: composer.json's post-autoload-dump runs ide-helper:* commands,
# but barryvdh/laravel-ide-helper is in require-dev. Under --no-dev those
# commands aren't registered, artisan exits 1, and `set -e` would abort the
# whole provision. So we skip composer scripts and run package:discover (the
# part that actually matters) ourselves afterwards.
log "Installing PHP dependencies (composer)..."
COMPOSER_FLAGS="--no-interaction --prefer-dist --no-scripts"
[[ "$PRODUCTION" == "true" ]] && COMPOSER_FLAGS="$COMPOSER_FLAGS --no-dev --optimize-autoloader"
COMPOSER_ALLOW_SUPERUSER=1 composer install $COMPOSER_FLAGS
"php${PHP_VERSION}" artisan package:discover --ansi
ok "Composer dependencies installed"

# App key
if ! grep -q "^APP_KEY=base64:" "${APP_DIR}/.env"; then
    "php${PHP_VERSION}" artisan key:generate --force
    ok "APP_KEY generated"
else
    ok "APP_KEY already set"
fi

# Frontend build (Vite)
log "Building frontend assets (npm)..."
npm ci
npm run build
ok "Frontend built"

# wa-bridge dependencies + its bridge-only .env
log "Installing wa-bridge (Baileys) dependencies..."
[[ -f "${APP_DIR}/wa-bridge/.env" ]] || cp "${APP_DIR}/wa-bridge/.env.example" "${APP_DIR}/wa-bridge/.env"
( cd "${APP_DIR}/wa-bridge" && npm ci )
ok "wa-bridge dependencies installed"

# zoom-bot (webinar assistant sidecar) dependencies + its Chromium.
# PLAYWRIGHT_BROWSERS_PATH pins the browser INSIDE the checkout: Playwright's
# default cache is per-user (~/.cache/ms-playwright), so a browser installed by
# the deploy user is invisible to the scheduler user and the bot dies at launch
# mid-webinar. Installing and launching against the same fixed path removes the
# whole class. --with-deps also installs Chromium's OS shared libraries.
ZOOM_BOT_DIR="${APP_DIR}/tools/zoom-bot"
log "Installing zoom-bot dependencies + Chromium..."
( cd "${ZOOM_BOT_DIR}" \
    && npm ci \
    && PLAYWRIGHT_BROWSERS_PATH="${ZOOM_BOT_DIR}/pw-browsers" npx playwright install --with-deps chromium )
# Point the app at the sidecar so the supervisor can launch it. Idempotent:
# only fills values that are blank/absent, never overwrites an operator's.
grep -q "^ZOOM_BOT_PATH=." "${APP_DIR}/.env" || sed -i "s#^ZOOM_BOT_PATH=.*#ZOOM_BOT_PATH=${ZOOM_BOT_DIR}#" "${APP_DIR}/.env"
grep -q "^PLAYWRIGHT_BROWSERS_PATH=." "${APP_DIR}/.env" || sed -i "s#^PLAYWRIGHT_BROWSERS_PATH=.*#PLAYWRIGHT_BROWSERS_PATH=${ZOOM_BOT_DIR}/pw-browsers#" "${APP_DIR}/.env"
ok "zoom-bot installed (verify with: php artisan zoom:bot-doctor)"

# Database migrations
log "Running migrations..."
"php${PHP_VERSION}" artisan migrate --force
ok "Migrations applied"

# Storage symlink + framework caches
"php${PHP_VERSION}" artisan storage:link 2>/dev/null || true
"php${PHP_VERSION}" artisan horizon:publish >/dev/null 2>&1 || true
if [[ "$PRODUCTION" == "true" ]]; then
    "php${PHP_VERSION}" artisan config:cache
    # route:cache fails hard if any route uses a closure — don't let a cache
    # step abort an otherwise-complete provision.
    "php${PHP_VERSION}" artisan route:cache || warn "route:cache failed (closure route?) — skipping route cache"
    "php${PHP_VERSION}" artisan view:cache
    ok "Config/route/view caches built"
fi

# ============================================================================
# 8. Permissions
# ============================================================================
log "Setting ownership and permissions..."
chown -R "${APP_USER}:${APP_GROUP}" "${APP_DIR}"
chmod -R ug+rwX "${APP_DIR}/storage" "${APP_DIR}/bootstrap/cache"
# setgid so new files in these dirs inherit APP_GROUP regardless of who creates them.
find "${APP_DIR}/storage" "${APP_DIR}/bootstrap/cache" -type d -exec chmod g+s {} +
# ACLs so BOTH the deploy user and the web user can read/write storage — and so
# NEW files inherit those rights (-d default ACLs). This is what prevents
# "permission denied" on laravel.log when one user created a file the other
# needs to write, which the ubuntu:www-data split otherwise causes.
if command -v setfacl >/dev/null; then
    setfacl -R  -m u:"${APP_USER}":rwX -m u:"${WEB_USER}":rwX "${APP_DIR}/storage" "${APP_DIR}/bootstrap/cache"
    setfacl -dR -m u:"${APP_USER}":rwX -m u:"${WEB_USER}":rwX "${APP_DIR}/storage" "${APP_DIR}/bootstrap/cache"
    ok "Permissions + ACLs set (owner ${APP_USER}:${APP_GROUP}; rwX for ${APP_USER} & ${WEB_USER})"
else
    warn "'acl' not installed — storage writes may break across users; run: apt-get install -y acl"
    ok "Permissions set (owner ${APP_USER}:${APP_GROUP})"
fi

# ============================================================================
# 9. Apache virtual host
# ============================================================================
log "Writing Apache virtual host..."
VHOST="/etc/apache2/sites-available/petav3.conf"
cat > "$VHOST" <<APACHE
<VirtualHost *:80>
    ServerName ${APP_DOMAIN}
    DocumentRoot ${APP_DIR}/public

    <Directory ${APP_DIR}/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    <FilesMatch \.php\$>
        SetHandler "proxy:unix:/run/php/php${PHP_VERSION}-fpm.sock|fcgi://localhost"
    </FilesMatch>

    ErrorLog \${APACHE_LOG_DIR}/petav3-error.log
    CustomLog \${APACHE_LOG_DIR}/petav3-access.log combined
</VirtualHost>
APACHE
a2dissite 000-default >/dev/null 2>&1 || true
a2ensite petav3 >/dev/null
apachectl configtest
systemctl reload apache2
ok "Virtual host enabled (DocumentRoot ${APP_DIR}/public)"

# ----------------------------------------------------------------------------
# 9.1 TLS — Let's Encrypt via certbot (Apache plugin)
# ----------------------------------------------------------------------------
DO_SSL=false
case "$ENABLE_SSL" in
    true)  DO_SSL=true ;;
    false) DO_SSL=false ;;
    auto)
        if [[ "$APP_DOMAIN" != "_" && -n "$CERTBOT_EMAIL" ]]; then DO_SSL=true; fi ;;
esac

if [[ "$DO_SSL" == "true" ]]; then
    if [[ "$APP_DOMAIN" == "_" ]]; then
        warn "ENABLE_SSL=true but APP_DOMAIN is unset ('_') — skipping certbot (needs a real domain)."
    elif [[ -z "$CERTBOT_EMAIL" ]]; then
        warn "ENABLE_SSL=true but CERTBOT_EMAIL is empty — skipping certbot (set CERTBOT_EMAIL=you@example.com)."
    else
        log "Obtaining TLS certificate for ${APP_DOMAIN} via certbot (Apache)..."
        apt-get install -y certbot python3-certbot-apache
        # --apache: install via the Apache plugin; --redirect: force http->https.
        if certbot --apache --non-interactive --agree-tos \
                --email "${CERTBOT_EMAIL}" \
                -d "${APP_DOMAIN}" --redirect; then
            ok "TLS certificate installed; HTTP redirects to HTTPS"
            # Point the app at https now that the cert is live.
            APP_URL="https://${APP_DOMAIN}"
            sed -i "s#^APP_URL=.*#APP_URL=${APP_URL}#" "${APP_DIR}/.env"
            [[ "$PRODUCTION" == "true" ]] && "php${PHP_VERSION}" artisan config:cache >/dev/null 2>&1 || true
            # certbot installs its own systemd timer for renewal; confirm it.
            systemctl is-enabled --quiet certbot.timer 2>/dev/null \
                && ok "Auto-renewal active (certbot.timer)" \
                || warn "certbot.timer not enabled — check 'systemctl status certbot.timer'"
        else
            warn "certbot failed (DNS not pointing here yet? port 80 blocked?) — site stays on HTTP. Re-run: certbot --apache -d ${APP_DOMAIN}"
        fi
    fi
else
    log "Skipping TLS (ENABLE_SSL=${ENABLE_SSL}). To enable later: certbot --apache -d ${APP_DOMAIN}"
fi

# ============================================================================
# 10. systemd services — Horizon + Baileys bridge + Inertia SSR
# ============================================================================
log "Installing systemd services..."
PHP_BIN="$(command -v "php${PHP_VERSION}")"
NODE_BIN="$(command -v node)"

cat > /etc/systemd/system/horizon.service <<UNIT
[Unit]
Description=Laravel Horizon (petav3 queue supervisor)
After=network.target redis-server.service mysql.service

[Service]
Type=simple
User=${APP_USER}
Group=${APP_GROUP}
Restart=always
RestartSec=3
WorkingDirectory=${APP_DIR}
ExecStart=${PHP_BIN} ${APP_DIR}/artisan horizon
ExecStop=${PHP_BIN} ${APP_DIR}/artisan horizon:terminate

[Install]
WantedBy=multi-user.target
UNIT

cat > /etc/systemd/system/baileys-wa-bridge.service <<UNIT
[Unit]
Description=Baileys WhatsApp Bridge (petav3 wa-bridge)
After=network.target mysql.service

[Service]
Type=simple
User=${APP_USER}
Group=${APP_GROUP}
Restart=always
RestartSec=5
Environment=NODE_ENV=production
WorkingDirectory=${APP_DIR}/wa-bridge
ExecStart=${NODE_BIN} ${APP_DIR}/wa-bridge/src/server.js

[Install]
WantedBy=multi-user.target
UNIT

# Laravel scheduler — the cron replacement that fires app/Console/Kernel.php
# (dowayai poll, WhatsApp backstops, Zoom sync). Horizon only
# drains the queue; without this unit no scheduled command ever runs. Content
# MUST stay byte-identical to the template in deploy-update.sh (which repairs /
# updates this unit on every deploy).
cat > /etc/systemd/system/petav3-scheduler.service <<UNIT
[Unit]
Description=petav3 Laravel scheduler (schedule:work)
After=network.target redis-server.service mysql.service

[Service]
Type=simple
User=${APP_USER}
Group=${APP_GROUP}
Restart=always
RestartSec=3
TimeoutStopSec=60
WorkingDirectory=${APP_DIR}
ExecStart=${PHP_BIN} ${APP_DIR}/artisan schedule:work
# Stop the scheduler ONLY, never its cgroup: zoom:run-bot detaches long-lived
# webinar bots that must survive a deploy's scheduler restart. The default
# control-group kill would SIGKILL a bot mid-webinar, leaving a phantom
# panelist broadcasting to the live audience.
KillMode=process

[Install]
WantedBy=multi-user.target
UNIT

# Inertia SSR render server — Node process (via artisan) that pre-renders the
# PUBLIC pages' HTML for crawlers/share-scrapers on :13714. Effective only when
# INERTIA_SSR_ENABLED=true in .env AND `npm run build` has produced
# bootstrap/ssr/ssr.js; if the daemon is down or the bundle missing, pages fall
# back to client-side rendering (degraded SEO, never an outage). MemoryMax is
# the OOM backstop for the long-lived render process; Restart=always recovers it.
cat > /etc/systemd/system/petav3-inertia-ssr.service <<UNIT
[Unit]
Description=petav3 Inertia SSR render server (:13714)
After=network.target

[Service]
Type=simple
User=${APP_USER}
Group=${APP_GROUP}
Restart=always
RestartSec=3
MemoryMax=512M
Environment=NODE_ENV=production
WorkingDirectory=${APP_DIR}
ExecStart=${PHP_BIN} ${APP_DIR}/artisan inertia:start-ssr
ExecStop=${PHP_BIN} ${APP_DIR}/artisan inertia:stop-ssr

[Install]
WantedBy=multi-user.target
UNIT

systemctl daemon-reload
systemctl enable --now horizon.service
systemctl enable --now baileys-wa-bridge.service
systemctl enable --now petav3-scheduler.service
systemctl enable --now petav3-inertia-ssr.service
ok "horizon.service, baileys-wa-bridge.service, petav3-scheduler.service and petav3-inertia-ssr.service enabled and started"

# ============================================================================
# Done
# ============================================================================
echo
log "Provisioning complete. Running verification..."
echo
if [[ -f "$(dirname "$0")/server-verify.sh" ]]; then
    bash "$(dirname "$0")/server-verify.sh" || warn "Verification reported issues — review above."
else
    warn "server-verify.sh not found next to this script; run it manually."
fi

echo
log "Next steps:"
echo "  • Review ${APP_DIR}/.env (mail, payment, WhatsApp, GCS credentials are placeholders)."
echo "  • TLS: pass APP_DOMAIN=<domain> CERTBOT_EMAIL=<email> to auto-provision a Let's Encrypt cert"
echo "        (or run it later: certbot --apache -d ${APP_DOMAIN})."
echo "  • Horizon dashboard is admin-gated at ${APP_URL}/horizon."
