#!/usr/bin/env bash
# Full production deploy: push (optional) + backend upgrade + frontend + health
#
# 自动识别远程 Docker（/opt/nexus）或 Supervisor（/www/wwwroot/...）运行时。
#
# Prerequisites on YOUR machine:
#   - SSH: ~/.ssh/config Host nexus  OR  export NEXUS_SSH="azureuser@20.24.218.235"
#   - Key:  export NEXUS_SSH_KEY=~/.ssh/id_rsa_nexus
#
# Usage:
#   cd "$NEXUS_ROOT"
#   bash deploy/pre_deploy_check.sh
#   bash deploy/deploy-production.sh

set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "${ROOT}"

SECRETS="${ROOT}/deploy/nexus-1panel.secrets.sh"
if [[ -f "$SECRETS" ]]; then
  # shellcheck disable=SC1090
  source "$SECRETS"
fi

NEXUS_SSH_HOST="${NEXUS_SSH:-nexus}"
SSH_OPTS=(-o BatchMode=yes -o ConnectTimeout=15)
if [[ -n "${NEXUS_SSH_KEY:-}" ]]; then
  SSH_OPTS+=(-i "${NEXUS_SSH_KEY}")
fi
ssh_cmd() { ssh "${SSH_OPTS[@]}" "${NEXUS_SSH_HOST}" "$@"; }
scp_cmd() { scp "${SSH_OPTS[@]}" "$@"; }

echo "═══ Nexus production deploy ═══"
echo "SSH target: ${NEXUS_SSH_HOST}"

if ! ssh_cmd "echo SSH OK" >/dev/null 2>&1; then
  echo "ERROR: Cannot SSH to ${NEXUS_SSH_HOST}" >&2
  echo "  Configure ~/.ssh/config (Host nexus) or set NEXUS_SSH / NEXUS_SSH_KEY" >&2
  exit 1
fi

REMOTE_DETECT=$(ssh_cmd 'bash -s' <<'REMOTE'
set -euo pipefail
docker_cmd() {
  if docker "$@" 2>/dev/null; then return 0; fi
  sudo docker "$@" 2>/dev/null
}
compose_cmd() {
  if docker compose "$@" 2>/dev/null; then return 0; fi
  sudo docker compose "$@" 2>/dev/null
}
for d in /opt/nexus /www/wwwroot/api.synaglobal.vip; do
  [[ -d "$d/server" ]] || continue
  echo "ROOT=$d"
  if [[ -f "$d/docker/.env.prod" ]] && compose_cmd version >/dev/null 2>&1; then
    prof="$d/docker/.host-profile"
    [[ -f "$prof" ]] || prof="$d/docker/profiles/2c8g.env"
    if [[ -f "$prof" ]]; then
      args=(-f "$d/docker/docker-compose.prod.yml")
      docker_cmd network inspect 1panel-network >/dev/null 2>&1 && \
        [[ -f "$d/docker/docker-compose.1panel.yml" ]] && \
        args+=(-f "$d/docker/docker-compose.1panel.yml")
      q=$(cd "$d" && compose_cmd "${args[@]}" \
        --env-file "$d/docker/.env.prod" --env-file "$prof" ps -q nexus 2>/dev/null || true)
      [[ -n "$q" ]] && echo RUNTIME=docker && exit 0
    fi
  fi
  if [[ -f "$d/deploy/nexus-1panel.sh" ]] && command -v nx >/dev/null 2>&1; then
    q=$(docker_cmd ps --format '{{.Names}}' 2>/dev/null | grep -E '^nexus-prod-nexus-' || true)
    [[ -n "$q" ]] && echo RUNTIME=docker && exit 0
  fi
  if command -v supervisorctl >/dev/null 2>&1 && supervisorctl status nexus >/dev/null 2>&1; then
    echo RUNTIME=supervisor
    exit 0
  fi
  echo RUNTIME=unknown
  exit 0
done
echo RUNTIME=none
REMOTE
)

DEPLOY_PATH="${NEXUS_DEPLOY_PATH:-$(echo "$REMOTE_DETECT" | sed -n 's/^ROOT=//p' | head -1)}"
RUNTIME="$(echo "$REMOTE_DETECT" | sed -n 's/^RUNTIME=//p' | head -1)"

if [[ -z "$DEPLOY_PATH" ]]; then
  DEPLOY_PATH="${NEXUS_DEPLOY_PATH:-/opt/nexus}"
fi
if [[ -z "$RUNTIME" || "$RUNTIME" == "none" ]]; then
  RUNTIME="unknown"
fi

echo "Deploy path: ${DEPLOY_PATH}"
echo "Runtime:     ${RUNTIME}"

if [[ "$RUNTIME" == "docker" ]]; then
  echo "▶ Docker: git pull + 镜像重建（前端在镜像内 vite build）..."
  ssh_cmd "cd ${DEPLOY_PATH} && sudo git fetch --all && sudo git reset --hard origin/main && \
    sudo env NEXUS_ROOT=${DEPLOY_PATH} bash ${DEPLOY_PATH}/deploy/nexus-1panel.sh upgrade"
elif [[ "$RUNTIME" == "supervisor" ]]; then
  echo "▶ Supervisor: git pull + restart..."
  ssh_cmd "cd ${DEPLOY_PATH} && git fetch --all && git reset --hard origin/main && supervisorctl restart nexus"

  echo "▶ Frontend: build + upload..."
  cd frontend && npx vite build && cd ..
  tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/
  scp_cmd /tmp/nexus-frontend.tar.gz "${NEXUS_SSH_HOST}:/tmp/nexus-frontend.tar.gz"
  ssh_cmd "cd ${DEPLOY_PATH}/web/app && tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"
  if ssh_cmd "test -f ${DEPLOY_PATH}/deploy/prune_frontend_assets.py"; then
    ssh_cmd "python3 ${DEPLOY_PATH}/deploy/prune_frontend_assets.py --dry-run"
    ssh_cmd "python3 ${DEPLOY_PATH}/deploy/prune_frontend_assets.py"
  fi
else
  echo "ERROR: 无法识别远程运行时（非 Docker 也非 Supervisor）" >&2
  echo "  请手动: ssh ${NEXUS_SSH_HOST} 'sudo nx update'" >&2
  exit 1
fi

if [[ "$RUNTIME" == "docker" ]]; then
  # Host web/app must match image build before sync_webapp_to_container (else stale assets overwrite container).
  echo "▶ Frontend: local vite build + upload to host web/app..."
  cd frontend && npx vite build && cd ..
  tar czf /tmp/nexus-frontend.tar.gz -C web/app index.html assets/
  scp_cmd /tmp/nexus-frontend.tar.gz "${NEXUS_SSH_HOST}:/tmp/nexus-frontend.tar.gz"
  ssh_cmd "cd ${DEPLOY_PATH}/web/app && sudo tar xzf /tmp/nexus-frontend.tar.gz && rm /tmp/nexus-frontend.tar.gz"

  echo "▶ Sync host web/app into container..."
  ssh_cmd "sudo env NEXUS_ROOT=${DEPLOY_PATH} NEXUS_PUBLISH_PORT=\$(grep -E '^NEXUS_PUBLISH_PORT=' ${DEPLOY_PATH}/docker/.env.prod 2>/dev/null | cut -d= -f2 | tr -d '\"' || echo 8600) bash ${DEPLOY_PATH}/deploy/sync_webapp_to_container.sh" || {
    echo "WARN: web/app sync failed — run sync_webapp_to_container.sh on server manually" >&2
  }
fi

sleep 3
PORT="$(ssh_cmd "grep -E '^NEXUS_PUBLISH_PORT=' ${DEPLOY_PATH}/docker/.env.prod 2>/dev/null | cut -d= -f2 | tr -d '\"'" 2>/dev/null || true)"
PORT="${PORT:-8600}"
HEALTH=$(ssh_cmd "curl -s http://127.0.0.1:${PORT}/health" 2>/dev/null || true)
SPA=$(ssh_cmd "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:${PORT}/app/" 2>/dev/null || echo "000")
echo "  /health → ${HEALTH}"
echo "  /app/   → ${SPA}"
if [[ "${HEALTH}" == "ok" && "${SPA}" == "200" ]]; then
  echo "✓ Deploy successful"
  if ssh_cmd "command -v crontab >/dev/null && crontab -l 2>/dev/null | grep -q nexus-health-monitor" 2>/dev/null; then
    echo "✓ Ops cron (health_monitor) already installed"
  else
    echo "▶ Installing ops cron (health_monitor + db_backup)…"
    if ssh_cmd "sudo env NEXUS_ROOT=${DEPLOY_PATH} bash ${DEPLOY_PATH}/deploy/install_ops_cron.sh" 2>/dev/null; then
      echo "✓ Ops cron installed"
    else
      echo "  提示: 远程 cron 安装失败，可在服务器执行: sudo nx cron"
    fi
  fi
else
  echo "✗ Verification failed — check logs on server" >&2
  exit 1
fi
