#!/usr/bin/env bash
#
# Deployment script for arb.admedia.com.
# Handles both first-time setup (new server) and routine code push deployments.
#
# Usage:
#   ./deploy.sh           # deploys current checked-out branch
#   ./deploy.sh <branch>  # deploys specific branch (e.g. ./deploy.sh main)
#
# First-time detection:
#   If the avatars table is empty (or unreachable), this script automatically
#   runs db:seed --class=ProductionSeeder to seed catalog data (avatars, voices,
#   ad accounts, Facebook pages). This is safe to run once; all seeders use
#   updateOrCreate so re-running on an existing DB is a no-op.
#

set -e

PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$PROJECT_DIR"

# ─── 1. Resolve PHP binary (prefer php8.5) ────────────────────────────────────
if [ -z "${PHP_BIN:-}" ]; then
    if command -v php8.5 >/dev/null 2>&1; then
        PHP_BIN="php8.5"
    elif command -v php >/dev/null 2>&1; then
        PHP_BIN="php"
    else
        echo "Error: PHP binary not found. Set PHP_BIN=/path/to/php8.5 ./deploy.sh" >&2
        exit 1
    fi
fi

echo "=================================================="
echo "==> Deploying ARB Application ($(date '+%Y-%m-%d %H:%M:%S'))"
echo "==> Using PHP binary: $($PHP_BIN -v | head -n 1)"
echo "=================================================="

# ─── 2. Git pull ──────────────────────────────────────────────────────────────
CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")"
DEPLOY_BRANCH="${1:-$CURRENT_BRANCH}"
CHANGED_FILES=""

if [ -n "$DEPLOY_BRANCH" ] && git rev-parse --git-dir >/dev/null 2>&1; then
    echo "==> Pulling latest changes from origin/$DEPLOY_BRANCH..."
    PREV_HEAD="$(git rev-parse HEAD 2>/dev/null || echo "")"
    git fetch origin "$DEPLOY_BRANCH"
    git pull origin "$DEPLOY_BRANCH"
    CHANGED_FILES="$(git diff --name-only "$PREV_HEAD" HEAD 2>/dev/null || echo "")"
else
    echo "==> Skipping git pull (not in a tracked branch)."
fi

# Note: vendor/ is tracked in git — composer install is intentionally omitted.

# ─── 3. Node & Puppeteer (only when package.json changed or node_modules missing) ─
if echo "$CHANGED_FILES" | grep -qE '^package(-lock)?\.json$' || [ ! -d "node_modules" ]; then
    if command -v npm >/dev/null 2>&1; then
        echo "==> package.json changed or node_modules missing. Running npm install..."
        npm install
        echo "==> Installing Puppeteer Chrome browser..."
        npx puppeteer browsers install chrome
    else
        echo "Warning: npm not found in PATH; skipping npm install and puppeteer." >&2
    fi
else
    echo "==> package.json unchanged; skipping npm install."
fi

# ─── 4. .env setup ────────────────────────────────────────────────────────────
if [ ! -f ".env" ]; then
    echo "==> No .env found. Copying from .env.example..."
    cp .env.example .env
    chmod 600 .env
    echo "==> Generating APP_KEY..."
    "$PHP_BIN" artisan key:generate --no-interaction
    echo ""
    echo "╔══════════════════════════════════════════════════════════════╗"
    echo "║  FIRST-TIME SETUP: .env created from .env.example           ║"
    echo "║                                                              ║"
    echo "║  Fill in these required values in .env before re-running:   ║"
    echo "║    DB_HOST / DB_DATABASE / DB_USERNAME / DB_PASSWORD         ║"
    echo "║    GEMINI_API_KEY                                            ║"
    echo "║    OPENAI_API_KEY                                            ║"
    echo "║    (Google Ads keys if using Google campaign management)     ║"
    echo "║                                                              ║"
    echo "║  APP_KEY has been generated and saved. Do not change it.    ║"
    echo "╚══════════════════════════════════════════════════════════════╝"
    echo ""
    exit 0
fi

# Auto-generate APP_KEY if .env exists but key is blank
if grep -qE '^APP_KEY=$' .env; then
    echo "==> APP_KEY is empty. Generating..."
    "$PHP_BIN" artisan key:generate --no-interaction
fi

# ─── 5. DB credentials — read from sysadmin ini if blank in .env ──────────────
# On this server, DB credentials are stored in /usr/share/php/arb_oci.ini
# by the sysadmin. If the .env still has blank DB_* values, auto-fill from it.
DB_INI="${DB_INI:-/usr/share/php/arb_oci.ini}"
if [ -f "$DB_INI" ]; then
    echo "==> Found DB ini at $DB_INI. Checking if DB credentials need filling..."
    ini_vars="$("$PHP_BIN" -r '
        $ini = parse_ini_file($argv[1], true)["database"] ?? [];
        foreach (["host", "user", "pass", "db"] as $key) {
            echo $key . "=" . escapeshellarg($ini[$key] ?? "") . "\n";
        }
    ' "$DB_INI")"
    eval "$(echo "$ini_vars" | sed -E 's/^host=/ini_host=/; s/^user=/ini_user=/; s/^pass=/ini_pass=/; s/^db=/ini_db=/')"

    # Write to .env only if the value is currently blank
    for pair in "DB_HOST=$ini_host" "DB_USERNAME=$ini_user" "DB_PASSWORD=$ini_pass" "DB_DATABASE=$ini_db"; do
        key="${pair%%=*}"
        val="${pair#*=}"
        if [ -n "$val" ] && grep -qE "^${key}=$" .env 2>/dev/null; then
            sed -i "s|^${key}=.*|${key}=\"${val}\"|" .env
            echo "    ==> Set $key from ini."
        fi
    done
fi

# Validate DB credentials are present before attempting to connect
DB_HOST_VAL="$(grep -E '^DB_HOST=' .env | cut -d'=' -f2- | tr -d '"' | tr -d "'")"
DB_USER_VAL="$(grep -E '^DB_USERNAME=' .env | cut -d'=' -f2- | tr -d '"' | tr -d "'")"
DB_PASS_VAL="$(grep -E '^DB_PASSWORD=' .env | cut -d'=' -f2- | tr -d '"' | tr -d "'")"
DB_NAME_VAL="$(grep -E '^DB_DATABASE=' .env | cut -d'=' -f2- | tr -d '"' | tr -d "'")"

if [ -z "$DB_HOST_VAL" ] || [ -z "$DB_USER_VAL" ] || [ -z "$DB_NAME_VAL" ]; then
    echo ""
    echo "Error: Database credentials are not configured in .env" >&2
    echo "       Set DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD and re-run." >&2
    echo "       (Or place /usr/share/php/arb_oci.ini on this server and re-run.)" >&2
    exit 1
fi

# ─── 6. Database Migrations ───────────────────────────────────────────────────
echo "==> Running database migrations..."
"$PHP_BIN" artisan migrate --force --no-interaction

# ─── 7. Initial Catalog & Connection Seeding ──────────────────────────────────
AVATAR_COUNT="$("$PHP_BIN" artisan tinker --execute 'echo \App\Models\Avatar::count();' 2>/dev/null | tail -1 | tr -d '[:space:]')"
if [ -z "$AVATAR_COUNT" ] || [ "$AVATAR_COUNT" = "0" ]; then
    echo "==> First-time setup detected (avatars table is empty). Seeding initial catalogs and connections..."
    "$PHP_BIN" artisan db:seed --class=ProductionSeeder --force --no-interaction
    "$PHP_BIN" artisan db:seed --class=PlatformConnectionSeeder --force --no-interaction
else
    echo "==> Catalog data already seeded ($AVATAR_COUNT avatars found), skipping ProductionSeeder."
    PLATFORM_CONN_COUNT="$("$PHP_BIN" artisan tinker --execute 'echo \App\Models\PlatformConnection::count();' 2>/dev/null | tail -1 | tr -d '[:space:]')"
    if [ -z "$PLATFORM_CONN_COUNT" ] || [ "$PLATFORM_CONN_COUNT" = "0" ]; then
        echo "==> Seeding platform connections (platform_connections table is empty)..."
        "$PHP_BIN" artisan db:seed --class=PlatformConnectionSeeder --force --no-interaction
    fi
fi

# ─── 8. Clear and warm caches ─────────────────────────────────────────────────
echo "==> Optimizing application caches (config, routes, views)..."
"$PHP_BIN" artisan optimize:clear --no-interaction
"$PHP_BIN" artisan optimize --no-interaction

# ─── 9. Public storage & Livewire assets ───────────────────────────────────────
if [ ! -L public/storage ] && [ ! -e public/storage ]; then
    echo "==> Creating storage symlink..."
    "$PHP_BIN" artisan storage:link --no-interaction
fi

if [ ! -f "public/vendor/livewire/manifest.json" ]; then
    echo "==> Publishing Livewire assets..."
    "$PHP_BIN" artisan livewire:publish --assets --no-interaction
fi

# ─── 10. Restart queue workers ────────────────────────────────────────────────
# Signals Supervisor workers to gracefully finish current job then reload new code.
echo "==> Signaling queue workers to restart..."
"$PHP_BIN" artisan queue:restart --no-interaction

# ─── 11. Re-apply permissions (fixes CLI umask / Nginx 500s) ──────────────────
if [ -f "./pf.sh" ]; then
    echo "==> Re-applying file permissions via pf.sh..."
    bash ./pf.sh
fi

# ─── 12. Reload PHP-FPM to flush OPcache ──────────────────────────────────────
if command -v systemctl >/dev/null 2>&1; then
    if systemctl is-active --quiet php8.5-fpm 2>/dev/null; then
        sudo systemctl reload php8.5-fpm 2>/dev/null \
            || echo "Notice: Could not reload php8.5-fpm via sudo (run manually if OPcache is enabled)."
    elif systemctl is-active --quiet php-fpm 2>/dev/null; then
        sudo systemctl reload php-fpm 2>/dev/null \
            || echo "Notice: Could not reload php-fpm via sudo (run manually if OPcache is enabled)."
    fi
fi

echo "=================================================="
echo "==> Deployment completed successfully!"
echo "=================================================="
