#!/bin/bash

# 生产环境部署脚本（集成数据库迁移）
# 功能：
# 1. 数据库备份
# 2. 代码更新
# 3. 容器重新部署
# 4. 数据库迁移
# 5. 验证和测试

set -e  # 遇到错误立即退出

# 配置变量
BACKUP_DIR="database_backups"
PROJECT_DIR="customer-recall"
LOG_FILE="deploy_$(date +%Y%m%d_%H%M%S).log"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# 错误处理函数
handle_error() {
    log_error "部署过程中发生错误，正在回滚..."
    
    # 如果容器已经停止，尝试恢复
    if ! docker compose ps | grep -q "Up"; then
        log_info "尝试恢复容器服务..."
        docker compose up -d || log_error "容器恢复失败"
    fi
    
    log_error "部署失败！请检查日志文件: $LOG_FILE"
    exit 1
}

# 设置错误处理
trap handle_error ERR

# 开始部署
log_info "🚀 开始生产环境部署（集成迁移系统）..."
log_info "📍 项目目录: $PROJECT_DIR"
log_info "📍 备份目录: $BACKUP_DIR"
log_info "📍 日志文件: $LOG_FILE"

# 检查项目目录
if [ ! -d "$PROJECT_DIR" ]; then
    log_error "项目目录不存在: $PROJECT_DIR"
    exit 1
fi

cd "$PROJECT_DIR"

# 第一步：创建数据库备份
log_info "📦 第一步：创建数据库备份..."
mkdir -p "$BACKUP_DIR"

TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/migration_backup_$TIMESTAMP.sql"

# 检查MySQL容器是否运行
if docker compose ps mysql | grep -q "Up"; then
    log_info "MySQL容器正在运行，创建备份..."
    
    # 使用docker exec执行mysqldump
    if docker compose exec -T mysql mysqldump -u root -pdev_password_123 \
        --single-transaction --routines --triggers callback_system > "$BACKUP_FILE"; then
        log_success "数据库备份完成: $BACKUP_FILE"
        
        # 验证备份文件
        if [ -s "$BACKUP_FILE" ]; then
            BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
            log_info "备份文件大小: $BACKUP_SIZE"
        else
            log_error "备份文件为空，备份可能失败"
            exit 1
        fi
    else
        log_error "数据库备份失败"
        exit 1
    fi
else
    log_warning "MySQL容器未运行，跳过备份"
fi

# 第二步：更新代码
log_info "📥 第二步：更新代码..."
if git pull origin master; then
    log_success "代码更新成功"
else
    log_error "代码更新失败"
    exit 1
fi

# 第三步：验证迁移文件
log_info "🔍 第三步：验证迁移文件..."
if [ -f "migrate.py" ] && [ -d "migrations" ]; then
    log_info "迁移系统文件存在，验证迁移文件..."
    
    # 在当前环境验证（如果有Python环境）
    if command -v python3 &> /dev/null; then
        if python3 migrate.py validate; then
            log_success "迁移文件验证通过"
        else
            log_warning "迁移文件验证失败，但继续部署"
        fi
    else
        log_info "本地无Python环境，将在容器中验证"
    fi
else
    log_warning "迁移系统文件不存在，使用传统部署方式"
fi

# 第四步：重新部署容器
log_info "🐳 第四步：重新部署容器..."
log_info "停止现有容器..."
docker compose down

log_info "重新构建并启动容器..."
if docker compose up -d --build; then
    log_success "容器部署成功"
else
    log_error "容器部署失败"
    exit 1
fi

# 等待容器启动
log_info "⏳ 等待容器完全启动..."
sleep 10

# 检查容器状态
log_info "🔍 检查容器状态..."
docker compose ps

# 第五步：执行数据库迁移
log_info "🗄️ 第五步：执行数据库迁移..."

# 等待数据库完全启动
log_info "等待数据库服务启动..."
for i in {1..30}; do
    if docker compose exec -T mysql mysql -u root -pdev_password_123 -e "SELECT 1;" &>/dev/null; then
        log_success "数据库连接成功"
        break
    fi
    
    if [ $i -eq 30 ]; then
        log_error "数据库启动超时"
        exit 1
    fi
    
    log_info "等待数据库启动... ($i/30)"
    sleep 2
done

# 执行迁移
if [ -f "migrate.py" ]; then
    log_info "使用迁移系统执行数据库更新..."
    
    # 检查迁移状态
    log_info "检查当前迁移状态..."
    docker compose exec -T patient_callback_app python migrate.py status || log_warning "无法获取迁移状态"
    
    # 试运行迁移
    log_info "试运行迁移（验证SQL语法）..."
    if docker compose exec -T patient_callback_app python migrate.py migrate --dry-run; then
        log_success "迁移试运行成功"
        
        # 执行实际迁移
        log_info "执行实际迁移..."
        if docker compose exec -T patient_callback_app python migrate.py migrate; then
            log_success "数据库迁移执行成功"
        else
            log_error "数据库迁移执行失败"
            exit 1
        fi
    else
        log_warning "迁移试运行失败，跳过迁移"
    fi
else
    log_info "使用传统方式执行数据导入..."
    if [ -f "safe_import_patients.py" ]; then
        if docker compose exec -T patient_callback_app python safe_import_patients.py; then
            log_success "数据导入成功"
        else
            log_warning "数据导入失败，但继续部署"
        fi
    else
        log_warning "数据导入脚本不存在"
    fi
fi

# 第六步：验证部署结果
log_info "✅ 第六步：验证部署结果..."

# 检查应用健康状态
log_info "检查应用健康状态..."
sleep 5
if curl -f http://localhost:5000/login &>/dev/null; then
    log_success "应用健康检查通过"
else
    log_warning "应用健康检查失败，但部署继续"
fi

# 检查数据库状态
log_info "检查数据库状态..."
docker compose exec -T mysql mysql -u root -pdev_password_123 -e "
USE callback_system;
SELECT 'users' as table_name, COUNT(*) as count FROM users
UNION ALL
SELECT 'patients', COUNT(*) FROM patients
UNION ALL
SELECT 'callback_records', COUNT(*) FROM callback_records;
" || log_warning "无法获取数据库统计信息"

# 第七步：清理旧备份
log_info "🧹 第七步：清理旧备份文件..."
find "$BACKUP_DIR" -name "migration_backup_*.sql" -mtime +7 -delete
log_success "旧备份文件清理完成"

# 部署完成
log_success "🎉 生产环境部署完成！"
log_info "📊 部署总结:"
log_info "  ✅ 数据库备份: $BACKUP_FILE"
log_info "  ✅ 代码更新: 完成"
log_info "  ✅ 容器部署: 完成"
log_info "  ✅ 数据库迁移: 完成"
log_info "  ✅ 验证测试: 完成"
log_info "  📍 备份位置: $BACKUP_DIR"
log_info "  📍 日志文件: $LOG_FILE"
log_info "  🕐 完成时间: $(date)"

# 显示最终状态
log_info "📋 最终容器状态:"
docker compose ps

log_info "📋 当前备份文件列表:"
ls -lh "$BACKUP_DIR"/migration_backup_*.sql 2>/dev/null || log_info "暂无备份文件"

log_success "部署脚本执行完成！"
