#!/bin/bash
set -Eeuo pipefail

echo "========================================="
echo "  TerManager2 - Entrypoint"
echo "========================================="

warn() {
    echo "[!] $*"
}

retry() {
    local attempts="$1"
    local delay="$2"
    shift 2

    local n=1
    until "$@"; do
        if [ "$n" -ge "$attempts" ]; then
            return 1
        fi
        warn "Command failed (attempt ${n}/${attempts}). Retrying in ${delay}s..."
        sleep "$delay"
        n=$((n + 1))
    done
}

upsert_env() {
    local key="$1"
    local value="$2"
    local env_file="$3"

    if grep -q "^${key}=" "$env_file"; then
        sed -i "s|^${key}=.*|${key}=${value}|" "$env_file"
    else
        echo "${key}=${value}" >> "$env_file"
    fi
}

read_env_value() {
    local key="$1"
    local env_file="$2"

    if [ ! -f "$env_file" ]; then
        return 0
    fi

    local line
    line=$(grep -E "^${key}=" "$env_file" | tail -n 1 || true)

    if [ -z "$line" ]; then
        return 0
    fi

    local value="${line#*=}"
    value="${value%\"}"
    value="${value#\"}"
    printf '%s' "$value"
}

# -----------------------------------------------
# 0. Application code is bind-mounted from host
# -----------------------------------------------
echo "[✓] Using bind-mounted application code from host."

# -----------------------------------------------
# 0b. Create required directories & fix permissions
# -----------------------------------------------
mkdir -p storage/framework/{cache,sessions,views}
mkdir -p storage/logs
mkdir -p storage/app
mkdir -p bootstrap/cache
if [ "$(id -u)" = "0" ]; then
    chown -R www-data:www-data storage bootstrap/cache
fi

# -----------------------------------------------
# 1. .env file (must exist before composer/artisan)
# -----------------------------------------------
if [ ! -f .env ]; then
    echo "[*] Creating .env from .env.example..."
    cp .env.example .env
fi

# Override .env values with Docker environment variables (if set)
# This ensures Dokploy env vars take precedence
if [ -n "${APP_KEY:-}" ]; then
    upsert_env "APP_KEY" "${APP_KEY}" .env
fi
if [ -n "${APP_URL:-}" ]; then
    upsert_env "APP_URL" "${APP_URL}" .env
fi
if [ -n "${DB_HOST:-}" ]; then
    upsert_env "DB_HOST" "${DB_HOST}" .env
fi
if [ -n "${DB_DATABASE:-}" ]; then
    upsert_env "DB_DATABASE" "${DB_DATABASE}" .env
fi
if [ -n "${DB_USERNAME:-}" ]; then
    upsert_env "DB_USERNAME" "${DB_USERNAME}" .env
fi
if [ -n "${DB_PASSWORD:-}" ]; then
    upsert_env "DB_PASSWORD" "${DB_PASSWORD}" .env
fi
if [ -n "${REDIS_HOST:-}" ]; then
    upsert_env "REDIS_HOST" "${REDIS_HOST}" .env
fi
if [ -n "${REDIS_PASSWORD:-}" ]; then
    upsert_env "REDIS_PASSWORD" "${REDIS_PASSWORD}" .env
fi
echo "[✓] .env file ready."

# -----------------------------------------------
# 2. Composer install (must run before artisan commands)
# -----------------------------------------------
if [ ! -f vendor/autoload.php ]; then
    echo "[*] Installing Composer dependencies..."
    retry 3 5 composer install --no-interaction --prefer-dist --optimize-autoloader --no-progress
else
    echo "[✓] Composer dependencies already installed."
fi

# -----------------------------------------------
# 3. Application key (persisted in storage volume)
# -----------------------------------------------
KEY_FILE="/var/www/html/storage/app/.app_key"

if [ -f "$KEY_FILE" ]; then
    # Restore key from persistent volume
    STORED_KEY=$(cat "$KEY_FILE")
    upsert_env "APP_KEY" "$STORED_KEY" .env
    echo "[✓] Application key restored from storage."
elif grep -q "^APP_KEY=$" .env; then
    # No stored key and .env has empty key: generate new one
    echo "[*] Generating application key..."
    php artisan key:generate --ansi
    # Save to persistent volume
    grep '^APP_KEY=' .env | cut -d= -f2- > "$KEY_FILE"
    echo "[✓] Application key saved to persistent storage."
else
    # .env already has a key (from env var override or .env.example), persist it
    grep '^APP_KEY=' .env | cut -d= -f2- > "$KEY_FILE"
    echo "[✓] Application key already set, saved to persistent storage."
fi

# -----------------------------------------------
# 4. NPM install & build assets
# -----------------------------------------------
if [ ! -d node_modules ]; then
    echo "[*] Installing NPM dependencies..."
    if [ -f package-lock.json ]; then
        retry 3 5 npm ci --no-audit --no-fund
    else
        retry 3 5 npm install --no-audit --no-fund
    fi
else
    echo "[✓] NPM dependencies already installed."
fi

if [ ! -f public/build/manifest.json ]; then
    echo "[*] Building frontend assets..."
    npm run build
else
    echo "[✓] Frontend assets already built."
fi

# -----------------------------------------------
# 5. Storage link
# -----------------------------------------------
if [ ! -L public/storage ]; then
    echo "[*] Creating storage symlink..."
    php artisan storage:link
else
    echo "[✓] Storage symlink already exists."
fi

# -----------------------------------------------
# 7. Run migrations
# -----------------------------------------------
echo "[*] Running database migrations..."
retry 10 3 php artisan migrate --force

# -----------------------------------------------
# 7b. Seed database on first container startup only
# -----------------------------------------------
SEED_MARKER_FILE="/var/www/html/storage/framework/.runtime_db_seeded"
RUN_DB_SEED_ON_FIRST_START="${RUN_DB_SEED_ON_FIRST_START:-true}"

if [ "$RUN_DB_SEED_ON_FIRST_START" = "true" ]; then
    if [ ! -f "$SEED_MARKER_FILE" ]; then
        echo "[*] First startup detected. Running database seed..."
        retry 5 3 php artisan db:seed --force
        touch "$SEED_MARKER_FILE"
        echo "[✓] Database seed completed and startup marker saved."
    else
        echo "[✓] Seed already executed on a previous startup."
    fi
else
    echo "[i] RUN_DB_SEED_ON_FIRST_START=false, skipping automatic seed."
fi

# -----------------------------------------------
# 7c. Ensure initial admin exists (first startup)
# -----------------------------------------------
ENSURE_INITIAL_ADMIN_ON_EMPTY_DB="${ENSURE_INITIAL_ADMIN_ON_EMPTY_DB:-true}"

INITIAL_ADMIN_NAME_VALUE="${INITIAL_ADMIN_NAME:-$(read_env_value INITIAL_ADMIN_NAME .env)}"
INITIAL_ADMIN_EMAIL_VALUE="${INITIAL_ADMIN_EMAIL:-$(read_env_value INITIAL_ADMIN_EMAIL .env)}"
INITIAL_ADMIN_PASSWORD_VALUE="${INITIAL_ADMIN_PASSWORD:-$(read_env_value INITIAL_ADMIN_PASSWORD .env)}"

if [ "$ENSURE_INITIAL_ADMIN_ON_EMPTY_DB" = "true" ]; then
    echo "[*] Ensuring initial administrator account..."
    if ! php artisan app:create-initial-admin \
        --name="$INITIAL_ADMIN_NAME_VALUE" \
        --email="$INITIAL_ADMIN_EMAIL_VALUE" \
        --password="$INITIAL_ADMIN_PASSWORD_VALUE" \
        --no-interaction; then
        warn "Initial admin creation failed. Set INITIAL_ADMIN_NAME, INITIAL_ADMIN_EMAIL and INITIAL_ADMIN_PASSWORD."
        exit 1
    fi
else
    echo "[i] ENSURE_INITIAL_ADMIN_ON_EMPTY_DB=false, skipping initial admin creation check."
fi

# -----------------------------------------------
# 8. Cache config/routes/views
# -----------------------------------------------
echo "[*] Caching configuration..."
php artisan config:cache || warn "config:cache failed; continuing startup."
php artisan route:cache || warn "route:cache failed; continuing startup."
php artisan view:cache || warn "view:cache failed; continuing startup."

echo "========================================="
echo "  TerManager2 - Ready!"
echo "========================================="

# -----------------------------------------------
# Execute CMD (default: php-fpm)
# -----------------------------------------------
exec "$@"
