#!/bin/bash
set -euo pipefail

# Deploy MacSync client to plum (MacBook) via rsync + SSH.
#
# Usage:
#   ./deploy-remote.sh                         # use default SERVER_URL
#   ./deploy-remote.sh http://10.0.0.11:3201   # override server URL
#   ./deploy-remote.sh uninstall               # uninstall from plum
#   ./deploy-remote.sh frontend                # re-sync webapp only (preserves TCC)

PLUM_HOST="${PLUM_HOST:-plum}"
SERVER_URL="${MAC_SYNC_SERVER_URL:-http://10.0.0.11:3201}"
STAGING_DIR="mac-sync-staging"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MAC_SYNC_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

print_step()    { echo -e "${GREEN}▸${NC} $1"; }
print_info()    { echo -e "${BLUE}ℹ${NC} $1"; }
print_warning() { echo -e "${YELLOW}⚠${NC} $1"; }
print_error()   { echo -e "${RED}✗${NC} $1"; }
print_success() { echo -e "${GREEN}✓${NC} $1"; }

KEEP_STAGING=false
for arg in "$@"; do
    case "$arg" in
        uninstall|frontend|--uninstall|--frontend|--skip-app) ;;
        --keep-staging) KEEP_STAGING=true ;;
        http://*|https://*) SERVER_URL="$arg" ;;
        --*) ;;
        *) SERVER_URL="$arg" ;;
    esac
done

echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE}  MacSync — Remote Deploy to $PLUM_HOST${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""

check_plum() {
    print_step "Checking SSH to $PLUM_HOST..."
    if ! ssh -o ConnectTimeout=5 "$PLUM_HOST" 'echo ok' >/dev/null 2>&1; then
        print_error "Cannot reach $PLUM_HOST — check SSH config"
        exit 1
    fi
    print_success "Connected"
}

cmd_install() {
    check_plum

    local remote_root="$STAGING_DIR/@applications/@mac-sync"

    # Sync mac-sync source
    print_step "Syncing @mac-sync source to $PLUM_HOST:~/$remote_root/..."
    ssh "$PLUM_HOST" "mkdir -p ~/$remote_root"
    # Exclude generated + VCS + dev-tool noise. plum regenerates Swift/node deps
    # as needed (Swift via `swift build` in install.sh; no node deps needed on plum).
    rsync -az --delete \
        --exclude '.build/' \
        --exclude 'DerivedData/' \
        --exclude '.swiftpm/' \
        --exclude 'node_modules/' \
        --exclude '.git/' \
        --exclude '.github/' \
        --exclude '.vscode/' \
        --exclude '.idea/' \
        --exclude '.DS_Store' \
        --exclude '*.log' \
        --exclude 'dist/' \
        --exclude 'coverage/' \
        --exclude '.cache/' \
        --exclude '.next/' \
        --exclude '.turbo/' \
        --exclude '.parcel-cache/' \
        --exclude '__pycache__/' \
        --exclude '*.pyc' \
        --exclude '.venv/' \
        "$MAC_SYNC_ROOT/" \
        "$PLUM_HOST:~/$remote_root/"

    # Sync local Swift package dependencies (referenced via relative paths in Package.swift)
    local swift_root
    swift_root="$(cd "$MAC_SYNC_ROOT/../../@packages/@swift" && pwd 2>/dev/null)" || true
    local tray_root
    tray_root="$(cd "$MAC_SYNC_ROOT/../../@packages/@tray" && pwd 2>/dev/null)" || true

    if [[ -d "${swift_root:-}" ]]; then
        print_step "Syncing Swift packages..."
        for pkg in "@macos/agent-core" "@macos/menu-bar" "@macos/sync-framework" "@foundations/logging" "@foundations/settings"; do
            local local_pkg="$swift_root/$pkg"
            [[ -d "$local_pkg" ]] || continue
            local remote_pkg="$STAGING_DIR/@packages/@swift/$pkg"
            ssh "$PLUM_HOST" "mkdir -p ~/$remote_pkg"
            rsync -az --delete \
                --exclude '.build/' --exclude '.swiftpm/' --exclude 'DerivedData/' \
                --exclude 'node_modules/' --exclude '.git/' --exclude '.DS_Store' \
                "$local_pkg/" "$PLUM_HOST:~/$remote_pkg/"
        done
        print_success "Swift packages synced"
    fi

    if [[ -d "${tray_root:-}" ]]; then
        for pkg in "tray-resources"; do
            local local_pkg="$tray_root/$pkg"
            [[ -d "$local_pkg" ]] || continue
            local remote_pkg="$STAGING_DIR/@packages/@tray/$pkg"
            ssh "$PLUM_HOST" "mkdir -p ~/$remote_pkg"
            rsync -az --delete \
                --exclude '.build/' --exclude '.swiftpm/' --exclude 'DerivedData/' \
                --exclude 'node_modules/' --exclude '.git/' --exclude '.DS_Store' \
                "$local_pkg/" "$PLUM_HOST:~/$remote_pkg/"
        done
    fi

    # Build webapp locally (plum may not have bun/pnpm)
    local web_src="$MAC_SYNC_ROOT/web"
    if [[ -d "$web_src" ]]; then
        print_step "Building webapp locally..."
        (cd "$web_src" && bun install --frozen-lockfile && bun run build) 2>&1
        if [[ -d "$web_src/dist" ]]; then
            print_step "Syncing web/dist to $PLUM_HOST..."
            rsync -az --delete \
                "$web_src/dist/" \
                "$PLUM_HOST:~/$remote_root/web/dist/"
            print_success "Webapp built and synced"
        else
            print_error "web/dist not produced"
            exit 1
        fi
    fi

    # Sync VERSION.json
    local version_file="$MAC_SYNC_ROOT/VERSION.json"
    [[ -f "$version_file" ]] && rsync -az "$version_file" "$PLUM_HOST:~/$remote_root/VERSION.json"

    # Run install.sh on plum
    print_step "Building and installing on $PLUM_HOST..."
    ssh -t "$PLUM_HOST" "cd ~/$remote_root && chmod +x deploy/install.sh && ./deploy/install.sh '$SERVER_URL'"

    # Verify
    print_step "Verifying agent status..."
    ssh "$PLUM_HOST" bash <<'CHECK'
sleep 2
if pgrep -x MacSyncApp >/dev/null; then
    echo "Agent is running"
    tail -5 ~/Library/Application\ Support/MacSync/stderr.log 2>/dev/null || true
else
    echo "Agent not running — grant Full Disk Access in System Settings"
fi
CHECK

    # Clean staging (unless --keep-staging)
    if [[ "$KEEP_STAGING" == "true" ]]; then
        print_info "Staging kept at ~/$STAGING_DIR (per --keep-staging)"
    else
        print_step "Cleaning staging..."
        ssh "$PLUM_HOST" "rm -rf ~/$STAGING_DIR"
        print_success "Staging cleaned"
    fi

    echo ""
    print_success "Deploy complete"
    print_info "Logs: ssh $PLUM_HOST 'tail -f ~/Library/Application\\ Support/MacSync/stderr.log'"
}

cmd_uninstall() {
    check_plum
    print_step "Uninstalling MacSync from $PLUM_HOST..."
    ssh -t "$PLUM_HOST" bash <<'UNINSTALL'
set -e
PLIST="$HOME/Library/LaunchAgents/com.lilith.mac-sync.plist"
APP="$HOME/Applications/MacSync.app"
if [[ -f "$PLIST" ]]; then
    launchctl unload "$PLIST" 2>/dev/null || true
    rm "$PLIST"
    echo "LaunchAgent removed"
fi
pkill -x MacSyncApp 2>/dev/null || true
[[ -d "$APP" ]] && rm -rf "$APP" && echo "App bundle removed"
echo "Uninstall complete"
UNINSTALL
}

cmd_frontend() {
    check_plum
    local web_src="$MAC_SYNC_ROOT/web"
    local remote_webapp="Applications/MacSync.app/Contents/Resources/webapp"

    print_step "Building webapp locally..."
    (cd "$web_src" && bun install --frozen-lockfile && bun run build)
    [[ -d "$web_src/dist" ]] || { print_error "web/dist not produced"; exit 1; }

    print_step "Syncing to $PLUM_HOST:~/$remote_webapp/..."
    rsync -az --delete "$web_src/dist/" "$PLUM_HOST:~/$remote_webapp/"
    print_success "Frontend synced"

    print_step "Re-signing app bundle (webapp update invalidates sealed resources)..."
    ssh "$PLUM_HOST" "codesign --remove-signature ~/Applications/MacSync.app 2>/dev/null; codesign -s - --force --deep ~/Applications/MacSync.app" \
        && print_success "App re-signed (ad-hoc)" \
        || print_warning "Re-signing failed — app may not launch"

    print_step "Restarting agent..."
    ssh "$PLUM_HOST" "pkill -x MacSyncApp 2>/dev/null || true"
    sleep 2
    ssh "$PLUM_HOST" "/usr/bin/open ~/Applications/MacSync.app 2>/dev/null; sleep 3 && pgrep -x MacSyncApp >/dev/null" \
        && print_success "Agent restarted" \
        || print_warning "Agent did not restart"

    echo ""
    print_success "Frontend deploy complete (TCC preserved)"
}

case "${1:-}" in
    uninstall) cmd_uninstall ;;
    frontend)  cmd_frontend ;;
    *)         cmd_install ;;
esac
