#!/usr/bin/env bash
# deploy.sh — 部署/升级 moziplus v2
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"

# 默认值
SOURCE_DIR="$PROJECT_DIR"
TARGET_DIR="${MOZIPLUS_V2_DIR:-$HOME/.sanguo_projects/sanguo_moziplus_v2}"
PM2_NAME="sanguo-moziplus-v2"
SKIP_BUILD=false

usage() {
  echo "Usage: $0 [options]"
  echo ""
  echo "Options:"
  echo "  --source=DIR    源码目录 (default: 项目开发目录)"
  echo "  --target=DIR    安装目标目录 (default: ~/.sanguo_projects/sanguo_moziplus_v2)"
  echo "  --skip-build    跳过前端构建"
  echo "  --version       显示当前部署版本"
  echo "  --rollback      回滚到上一个部署版本"
  echo "  -h, --help      显示帮助"
  exit 0
}

for arg in "$@"; do
  case "$arg" in
    --source=*) SOURCE_DIR="${arg#*=}" ;;
    --target=*) TARGET_DIR="${arg#*=}" ;;
    --skip-build) SKIP_BUILD=true ;;
    --version) ACTION=version ;;
    --rollback) ACTION=rollback ;;
    --health-check) ;; # 保留兼容，无额外操作
    -h|--help) usage ;;
  esac
done

ACTION="${ACTION:-deploy}"

# ── 部署历史文件 ──
HISTORY_FILE="$TARGET_DIR/data/deploy-history.jsonl"

# ── version 分支 ──
if [ "$ACTION" = "version" ]; then
  if [ -f "$HISTORY_FILE" ]; then
    LAST_COMMIT=$(tail -1 "$HISTORY_FILE" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("commit","unknown"))' 2>/dev/null || echo "unknown")
    echo "$LAST_COMMIT"
  else
    echo "No deployment history found."
  fi
  exit 0
fi

# ── rollback 分支 ──
if [ "$ACTION" = "rollback" ]; then
  if [ ! -f "$HISTORY_FILE" ]; then
    echo "❌ No deployment history, cannot rollback."
    exit 1
  fi
  LINE_COUNT=$(wc -l < "$HISTORY_FILE")
  if [ "$LINE_COUNT" -lt 2 ]; then
    echo "❌ Not enough history for rollback (need at least 2 entries)."
    exit 1
  fi
  ROLLBACK_COMMIT=$(tail -2 "$HISTORY_FILE" | head -1 | python3 -c 'import sys,json; print(json.load(sys.stdin).get("commit",""))' 2>/dev/null || echo "")
  if [ -z "$ROLLBACK_COMMIT" ]; then
    echo "❌ Could not parse previous commit from history."
    exit 1
  fi
  echo "🔄 Rolling back to commit: $ROLLBACK_COMMIT"
  # 保存当前分支/commit 以便恢复
  CURRENT_REF=$(git -C "$SOURCE_DIR" rev-parse HEAD 2>/dev/null || echo "")
  # checkout 到目标 commit
  git -C "$SOURCE_DIR" checkout "$ROLLBACK_COMMIT" 2>/dev/null
  # 使用 DEPLOY_OVERRIDE_COMMIT 显式传 commit hash
  DEPLOY_OVERRIDE_COMMIT="$ROLLBACK_COMMIT" bash "$0" --source="$SOURCE_DIR" --target="$TARGET_DIR" --skip-build
  # 恢复到原来的 commit
  if [ -n "$CURRENT_REF" ]; then
    git -C "$SOURCE_DIR" checkout "$CURRENT_REF" 2>/dev/null || true
  fi
  exit 0
fi

echo "🚀 Deploying moziplus v2"
echo "   Source: $SOURCE_DIR"
echo "   Target: $TARGET_DIR"

# ── 前置检查 ──
echo ""
echo "📋 Pre-flight checks..."

if ! command -v python3 &>/dev/null; then
  echo "❌ python3 not found" && exit 1
fi
PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
echo "   Python: $PYTHON_VERSION ✅"

if ! command -v pm2 &>/dev/null; then
  echo "❌ pm2 not found" && exit 1
fi
echo "   PM2: $(pm2 --version) ✅"

if [ ! -d "$SOURCE_DIR/src" ]; then
  echo "❌ Source directory invalid: $SOURCE_DIR/src not found" && exit 1
fi

# ── 前端构建 ──
if [ "$SKIP_BUILD" = false ]; then
  echo ""
  echo "🔨 Building frontend..."
  bash "$SCRIPT_DIR/build-frontend.sh"
else
  echo ""
  echo "⏭️  Skipping frontend build (--skip-build)"
  # 确保前端 dist 存在
  if [ ! -d "$SOURCE_DIR/src/frontend/dist" ]; then
    echo "❌ Frontend dist not found. Run without --skip-build first." && exit 1
  fi
fi

# ── 创建目标目录 ──
FIRST_INSTALL=false
if [ ! -d "$TARGET_DIR" ]; then
  FIRST_INSTALL=true
  echo ""
  echo "📁 Creating target directory: $TARGET_DIR"
  mkdir -p "$TARGET_DIR"
fi

# ── 同步代码 ──
echo ""
echo "🔄 Syncing code..."
rsync -a --delete \
  --exclude='.git/' \
  --exclude='docs/' \
  --exclude='tests/' \
  --exclude='scripts/' \
  --exclude='data/' \
  --exclude='logs/' \
  --exclude='inbox/' \
  --exclude='node_modules/' \
  --exclude='tsconfig.tsbuildinfo' \
  --exclude='__pycache__/' \
  --exclude='.venv/' \
  --exclude='.DS_Store' \
  --exclude='config/' \
  "$SOURCE_DIR/" "$TARGET_DIR/"

# 但不覆盖运行时配置和数据
# rsync --delete 不影响 exclude 的目录

echo "   Code synced ✅"

# ── 确保目录结构 ──
mkdir -p "$TARGET_DIR/data"
mkdir -p "$TARGET_DIR/logs"
mkdir -p "$TARGET_DIR/inbox"

# 确保默认配置存在（不覆盖已有配置）
if [ ! -f "$TARGET_DIR/config/default.yaml" ]; then
  if [ -f "$SOURCE_DIR/config/default.yaml" ]; then
    cp "$SOURCE_DIR/config/default.yaml" "$TARGET_DIR/config/default.yaml"
    echo "   Created default config ✅"
  fi
fi

if [ ! -f "$TARGET_DIR/config/guardrails.yaml" ]; then
  if [ -f "$SOURCE_DIR/config/guardrails.yaml" ]; then
    cp "$SOURCE_DIR/config/guardrails.yaml" "$TARGET_DIR/config/guardrails.yaml"
    echo "   Created guardrails config ✅"
  fi
fi

# ── PM2 管理 ──
echo ""
if [ "$FIRST_INSTALL" = true ]; then
  echo "🆕 First install — starting with PM2..."
  cd "$TARGET_DIR"
  pm2 start ecosystem.config.cjs
else
  echo "♻️  Upgrading — restarting PM2..."
  pm2 restart "$PM2_NAME" --update-env
fi
pm2 save

# ── 前端健康检查 ──
echo "   Checking frontend..."
FRONTEND_OK=false
for i in $(seq 1 5); do
  if curl -sf http://localhost:8083/ >/dev/null 2>&1; then
    FRONTEND_OK=true
    break
  fi
  sleep 1
done
if [ "$FRONTEND_OK" = true ]; then
  echo "   Frontend check passed ✅"
else
  echo "   ⚠️  Frontend check timeout"
fi

# ── 后端健康检查 ──
echo "   Checking backend..."
HEALTH_URL="http://localhost:8083/api/daemon/status"
OK=false
for i in $(seq 1 10); do
  if curl -sf "$HEALTH_URL" >/dev/null 2>&1; then
    OK=true
    break
  fi
  sleep 1
done

if [ "$OK" = true ]; then
  echo "   Health check passed ✅"
else
  echo "   ⚠️  Health check timeout (service may still be starting)"
  echo "   Check: pm2 logs $PM2_NAME"
fi

# ── 记录部署历史 ──
mkdir -p "$(dirname "$HISTORY_FILE")"
if [ -n "${DEPLOY_OVERRIDE_COMMIT:-}" ]; then
  DEPLOYED_COMMIT="$DEPLOY_OVERRIDE_COMMIT"
else
  DEPLOYED_COMMIT=$(git -C "$SOURCE_DIR" rev-parse --short HEAD 2>/dev/null || echo "unknown")
fi
DEPLOY_TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
DEPLOY_SOURCE="${SOURCE_DIR}"
HISTORY_ENTRY=$(printf '%s' '{"timestamp":"'$DEPLOY_TIMESTAMP'","commit":"'$DEPLOYED_COMMIT'","source":"'$DEPLOY_SOURCE'"}')
echo "$HISTORY_ENTRY" >> "$HISTORY_FILE"
# 保留最近 10 条
if [ -f "$HISTORY_FILE" ]; then
  TMPFILE=$(mktemp)
  tail -10 "$HISTORY_FILE" > "$TMPFILE"
  mv "$TMPFILE" "$HISTORY_FILE"
fi
echo "   Deploy history recorded ($DEPLOYED_COMMIT) ✅"

# ── 完成 ──
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [ "$FIRST_INSTALL" = true ]; then
  echo "✅ moziplus v2 installed successfully!"
else
  echo "✅ moziplus v2 upgraded successfully!"
fi
echo "   URL: http://localhost:8083/"
echo "   PM2: pm2 status $PM2_NAME"
echo "   Logs: pm2 logs $PM2_NAME"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
