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

REMOTE_USER=${REMOTE_USER:-ubuntu}
REMOTE_HOST=${REMOTE_HOST:-vps-4d8abcb7.vps.ovh.net}
REMOTE_BASE=${REMOTE_BASE:-/srv/myroadtrip}
REMOTE_REPO=${REMOTE_REPO:-${REMOTE_BASE}/repo}
REMOTE_APP_USER=${REMOTE_APP_USER:-myroadtrip}
SSH_OPTS=${SSH_OPTS:-"-o StrictHostKeyChecking=no"}
SSH_PASS=${SSH_PASS:-}
SSH_WRAP=()

if [[ -n "$SSH_PASS" ]]; then
  if ! command -v sshpass >/dev/null 2>&1; then
    echo "sshpass is required when SSH_PASS is set. Install it (brew install hudochenkov/sshpass/sshpass or apt install sshpass)." >&2
    exit 1
  fi
  SSH_WRAP=(sshpass -p "$SSH_PASS")
fi

remote_ssh() {
  if [[ ${#SSH_WRAP[@]} -gt 0 ]]; then
    "${SSH_WRAP[@]}" ssh $SSH_OPTS "$REMOTE_USER@$REMOTE_HOST" "$@"
  else
    ssh $SSH_OPTS "$REMOTE_USER@$REMOTE_HOST" "$@"
  fi
}

remote_scp() {
  local src="$1"
  local dest="$2"
  if [[ ${#SSH_WRAP[@]} -gt 0 ]]; then
    "${SSH_WRAP[@]}" scp $SSH_OPTS "$src" "$REMOTE_USER@$REMOTE_HOST:$dest"
  else
    scp $SSH_OPTS "$src" "$REMOTE_USER@$REMOTE_HOST:$dest"
  fi
}

FILE_ENTRIES=(
  ".env::$REMOTE_REPO/.env"
  ".env.development::$REMOTE_REPO/.env.development"
  ".env.production::$REMOTE_BASE/.env.production"
  "apps/api/.env::$REMOTE_REPO/apps/api/.env"
  "apps/api/.env.production::$REMOTE_REPO/apps/api/.env.production"
  "apps/web/.env::$REMOTE_REPO/apps/web/.env"
  "apps/web/.env.production::$REMOTE_REPO/apps/web/.env.production"
  "serviceAccount.json::$REMOTE_BASE/serviceAccount.json"
)

DIR_ENTRIES=(
  "firebase::$REMOTE_BASE/firebase"
)

# Create a temporary directory for staging
STAGING_DIR=$(mktemp -d)
mkdir -p "$STAGING_DIR/files"

# Stage files
for entry in "${FILE_ENTRIES[@]}"; do
  src="${entry%%::*}"
  dest="${entry##*::}"
  
  if [[ -f "$src" ]]; then
    # Create directory structure in staging
    # We use a flat structure with a mapping file to handle absolute paths
    cp "$src" "$STAGING_DIR/files/$(basename "$src")-$((RANDOM))"
    # Store mapping: local_staging_path::remote_dest
    echo "$STAGING_DIR/files/$(basename "$src")-$((RANDOM))::$dest" >> "$STAGING_DIR/mapping.txt"
  else
    echo "Warning: Skipping missing file $src"
  fi
done

# Create tarball of staging directory
TAR_PATH=$(mktemp)
tar -czf "$TAR_PATH" -C "$STAGING_DIR" .

# Upload tarball (ONE password prompt)
echo "Uploading environment bundle..."
REMOTE_TMP="/tmp/env-bundle-$(date +%s).tgz"
remote_scp "$TAR_PATH" "$REMOTE_TMP"

# Extract and distribute on server (ONE password prompt)
echo "Applying configuration on server..."
remote_ssh "
  TMP_EXTRACT=\$(mktemp -d)
  tar -xzf '$REMOTE_TMP' -C \"\$TMP_EXTRACT\"
  
  # Process mapping file
  while IFS='::' read -r local_name remote_dest; do
    # The local_name in mapping is the full local path, we need just the filename
    filename=\$(basename \"\$local_name\")
    src=\"\$TMP_EXTRACT/files/\$filename\"
    
    if [[ -f \"\$src\" ]]; then
      dest_dir=\$(dirname \"\$remote_dest\")
      sudo install -d -m 750 -o $REMOTE_APP_USER -g $REMOTE_APP_USER \"\$dest_dir\"
      sudo mv \"\$src\" \"\$remote_dest\"
      sudo chown $REMOTE_APP_USER:$REMOTE_APP_USER \"\$remote_dest\"
      if [[ "\$filename" == "serviceAccount.json" ]]; then
        sudo chmod 644 \"\$remote_dest\"
      else
        sudo chmod 600 \"\$remote_dest\"
      fi
      echo \"Updated \$remote_dest\"
    fi
  done < \"\$TMP_EXTRACT/mapping.txt\"
  
  # Clean up
  rm -rf \"\$TMP_EXTRACT\" \"$REMOTE_TMP\"
"

# Cleanup local
rm -rf "$STAGING_DIR" "$TAR_PATH"
echo "Environment sync complete."
