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

# Build Vite client + SSR assets locally and upload them to cPanel (production or sandbox).
# Remote hosts cannot run `npm run build`.
#
# Usage (from laravel/):
#   ./deploy-assets.sh                    # production (default)
#   ./deploy-assets.sh --sandbox          # public_html/sandbox.servdiary.com
#   ./deploy-assets.sh --target sandbox
#   ./deploy-assets.sh --skip-build
#   ./deploy-assets.sh --with-node-modules   # SSR runtime deps (vue, inertia, etc.)
#   ./deploy-assets.sh --password 'your-password'
#   DEPLOY_PASSWORD='your-password' ./deploy-assets.sh
#
# Override defaults with env vars:
#   DEPLOY_HOST=my2880@srv07.queenbmarketing.uk
#   DEPLOY_TARGET=production|sandbox
#   DEPLOY_PATH=...                       # overrides DEPLOY_TARGET path preset
#   DEPLOY_WITH_NODE_MODULES=1            # same as --with-node-modules
#   DEPLOY_PASSWORD=...

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

DEPLOY_HOST="${DEPLOY_HOST:-my2880@srv07.queenbmarketing.uk}"
DEPLOY_TARGET="${DEPLOY_TARGET:-production}"
DEPLOY_PATH="${DEPLOY_PATH:-}"
DEPLOY_PASSWORD="${DEPLOY_PASSWORD:-}"
SKIP_BUILD=0
WITH_NODE_MODULES="${DEPLOY_WITH_NODE_MODULES:-0}"
ASKPASS_FILE=""
NODE_MODULES_ARCHIVE=""

deploy_path_for_target() {
    case "$1" in
        production)
            echo "public_html/servdiary.com/laravel"
            ;;
        sandbox)
            echo "public_html/sandbox.servdiary.com/laravel"
            ;;
        *)
            echo "Unknown deploy target: $1 (use production or sandbox)" >&2
            exit 1
            ;;
    esac
}

cleanup() {
    if [[ -n "$ASKPASS_FILE" && -f "$ASKPASS_FILE" ]]; then
        rm -f "$ASKPASS_FILE"
    fi
    if [[ -n "$NODE_MODULES_ARCHIVE" && -f "$NODE_MODULES_ARCHIVE" ]]; then
        rm -f "$NODE_MODULES_ARCHIVE"
    fi
}
trap cleanup EXIT

while [[ $# -gt 0 ]]; do
    case "$1" in
        --sandbox)
            DEPLOY_TARGET=sandbox
            shift
            ;;
        --target)
            if [[ $# -lt 2 || -z "${2:-}" ]]; then
                echo "--target requires a value (production or sandbox)" >&2
                exit 1
            fi
            DEPLOY_TARGET="$2"
            shift 2
            ;;
        --target=*)
            DEPLOY_TARGET="${1#*=}"
            shift
            ;;
        --skip-build)
            SKIP_BUILD=1
            shift
            ;;
        --with-node-modules)
            WITH_NODE_MODULES=1
            shift
            ;;
        --password)
            if [[ $# -lt 2 || -z "${2:-}" ]]; then
                echo "--password requires a value" >&2
                exit 1
            fi
            DEPLOY_PASSWORD="$2"
            shift 2
            ;;
        --password=*)
            DEPLOY_PASSWORD="${1#*=}"
            shift
            ;;
        -h|--help)
            sed -n '2,22p' "$0"
            exit 0
            ;;
        *)
            echo "Unknown argument: $1" >&2
            exit 1
            ;;
    esac
done

if [[ -z "$DEPLOY_PATH" ]]; then
    DEPLOY_PATH="$(deploy_path_for_target "$DEPLOY_TARGET")"
fi

if [[ -z "$DEPLOY_PASSWORD" ]]; then
    if [[ -t 0 ]]; then
        read -r -s -p "Password for ${DEPLOY_HOST}: " DEPLOY_PASSWORD
        echo
    fi
fi

if [[ -z "$DEPLOY_PASSWORD" ]]; then
    echo "No password provided. Pass --password, set DEPLOY_PASSWORD, or enter it when prompted." >&2
    exit 1
fi

export DEPLOY_PASSWORD

REMOTE_ROOT="~/${DEPLOY_PATH}"

remote_ssh() {
    if command -v sshpass >/dev/null 2>&1; then
        sshpass -p "$DEPLOY_PASSWORD" ssh \
            -o StrictHostKeyChecking=accept-new \
            "$DEPLOY_HOST" \
            "$@"
        return
    fi

    if [[ -z "$ASKPASS_FILE" ]]; then
        ASKPASS_FILE="$(mktemp)"
        cat > "$ASKPASS_FILE" <<'ASK'
#!/bin/sh
printf '%s\n' "$DEPLOY_PASSWORD"
ASK
        chmod 700 "$ASKPASS_FILE"
    fi

    DISPLAY="${DISPLAY:-:0}" \
    SSH_ASKPASS="$ASKPASS_FILE" \
    SSH_ASKPASS_REQUIRE=force \
    setsid -w ssh \
        -o StrictHostKeyChecking=accept-new \
        "$DEPLOY_HOST" \
        "$@"
}

remote_scp() {
    if command -v sshpass >/dev/null 2>&1; then
        sshpass -p "$DEPLOY_PASSWORD" scp \
            -o StrictHostKeyChecking=accept-new \
            -r \
            "$@"
        return
    fi

    if [[ -z "$ASKPASS_FILE" ]]; then
        ASKPASS_FILE="$(mktemp)"
        cat > "$ASKPASS_FILE" <<'ASK'
#!/bin/sh
printf '%s\n' "$DEPLOY_PASSWORD"
ASK
        chmod 700 "$ASKPASS_FILE"
    fi

    DISPLAY="${DISPLAY:-:0}" \
    SSH_ASKPASS="$ASKPASS_FILE" \
    SSH_ASKPASS_REQUIRE=force \
    setsid -w scp \
        -o StrictHostKeyChecking=accept-new \
        -r \
        "$@"
}

echo "==> Checking remote Laravel root at ${DEPLOY_HOST}:${REMOTE_ROOT}"
if ! remote_ssh "test -d ${REMOTE_ROOT}"; then
    echo "Remote Laravel root not found: ${REMOTE_ROOT}" >&2
    echo "Set DEPLOY_PATH to your remote Laravel root, e.g.:" >&2
    echo "  DEPLOY_PATH=public_html/sandbox.servdiary.com/laravel ./deploy-assets.sh --sandbox" >&2
    exit 1
fi

echo "==> Ensuring remote asset directories exist"
remote_ssh "mkdir -p ${REMOTE_ROOT}/public/build ${REMOTE_ROOT}/bootstrap/ssr"

if [[ "$SKIP_BUILD" -eq 0 ]]; then
    echo "==> Building client and SSR assets"
    npm run build
else
    echo "==> Skipping build (--skip-build)"
fi

if [[ ! -d public/build ]]; then
    echo "Missing public/build — run a build first." >&2
    exit 1
fi

if [[ ! -d bootstrap/ssr ]]; then
    echo "Missing bootstrap/ssr — run a build first." >&2
    exit 1
fi

echo "==> Uploading public/build -> ${DEPLOY_HOST}:${REMOTE_ROOT}/public/build/"
remote_scp public/build/. "${DEPLOY_HOST}:${REMOTE_ROOT}/public/build/"

echo "==> Uploading bootstrap/ssr -> ${DEPLOY_HOST}:${REMOTE_ROOT}/bootstrap/ssr/"
remote_scp bootstrap/ssr/. "${DEPLOY_HOST}:${REMOTE_ROOT}/bootstrap/ssr/"

if [[ "$WITH_NODE_MODULES" -eq 1 ]]; then
    if [[ ! -d node_modules ]]; then
        if [[ "$SKIP_BUILD" -eq 0 ]]; then
            echo "==> Installing npm dependencies"
            npm ci
        else
            echo "Missing node_modules — run npm ci first or omit --skip-build." >&2
            exit 1
        fi
    fi

    echo "==> Packaging node_modules for upload (this may take a while)"
    NODE_MODULES_ARCHIVE="$(mktemp /tmp/servdiary-node_modules.XXXXXX.tar.gz)"
    tar -czf "$NODE_MODULES_ARCHIVE" node_modules package.json package-lock.json

    echo "==> Uploading node_modules -> ${DEPLOY_HOST}:${REMOTE_ROOT}/"
    remote_scp "$NODE_MODULES_ARCHIVE" "${DEPLOY_HOST}:${REMOTE_ROOT}/node_modules.deploy.tar.gz"
    remote_ssh "cd ${REMOTE_ROOT} && rm -rf node_modules && tar -xzf node_modules.deploy.tar.gz && rm node_modules.deploy.tar.gz"

    echo "==> node_modules deployed ($(du -sh node_modules | cut -f1) uncompressed locally)"
fi

echo "==> Assets deployed (${DEPLOY_TARGET}) to ${DEPLOY_HOST}:${REMOTE_ROOT}"
