#!/bin/bash

# PicAnalysis Docker 部署脚本
# 使用方法: ./deploy.sh [command]

set -e

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

# 打印带颜色的消息
print_info() {
    echo -e "${BLUE}ℹ${NC} $1"
}

print_success() {
    echo -e "${GREEN}✓${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}⚠${NC} $1"
}

print_error() {
    echo -e "${RED}✗${NC} $1"
}

# 检查 Docker 是否安装
check_docker() {
    if ! command -v docker &> /dev/null; then
        print_error "Docker 未安装，请先安装 Docker Engine"
        exit 1
    fi

    if ! command -v docker compose &> /dev/null && ! docker compose version &> /dev/null; then
        print_error "Docker Compose 未安装，请先安装 Docker Compose"
        exit 1
    fi

    print_success "Docker 环境检查通过"
}

# 检查环境变量文件
check_env() {
    if [ ! -f .env ]; then
        print_warning ".env 文件不存在，从模板创建..."

        if [ -f .env.production.example ]; then
            cp .env.production.example .env
            print_info "已创建 .env 文件"

            # 生成随机 JWT_SECRET
            JWT_SECRET=$(openssl rand -base64 32 2>/dev/null || echo "change-this-secret-key-in-production")
            sed -i "s/CHANGE_THIS_TO_A_STRONG_RANDOM_KEY/$JWT_SECRET/g" .env 2>/dev/null || \
            sed -i.bak "s/CHANGE_THIS_TO_A_STRONG_RANDOM_KEY/$JWT_SECRET/g" .env

            print_success "已自动生成 JWT_SECRET"
            print_warning "请检查 .env 文件并根据需要修改其他配置"
        else
            print_error "找不到 .env.production.example 模板文件"
            exit 1
        fi
    else
        print_success ".env 文件已存在"
    fi
}

# 启动服务
start_services() {
    print_info "启动 Docker 服务..."
    docker compose up -d

    print_success "服务启动成功"
    echo ""
    print_info "访问地址:"
    echo "  - 前端: http://localhost:80"
    echo "  - 后端: http://localhost:80/api"
    echo ""
    print_info "默认测试账号:"
    echo "  - 用户名: testuser"
    echo "  - 密码: Password123@"
}

# 停止服务
stop_services() {
    print_info "停止 Docker 服务..."
    docker compose stop
    print_success "服务已停止"
}

# 重启服务
restart_services() {
    print_info "重启 Docker 服务..."
    docker compose restart
    print_success "服务已重启"
}

# 查看日志
view_logs() {
    SERVICE=$1
    if [ -z "$SERVICE" ]; then
        docker compose logs -f
    else
        docker compose logs -f "$SERVICE"
    fi
}

# 查看状态
view_status() {
    docker compose ps
}

# 清理服务
clean_services() {
    print_warning "这将删除所有容器、卷和镜像，请确认是否继续? (y/N)"
    read -r confirm

    if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
        print_info "清理 Docker 资源..."
        docker compose down -v --rmi all
        print_success "清理完成"
    else
        print_info "已取消清理操作"
    fi
}

# 重新构建
rebuild() {
    print_info "重新构建并启动服务..."
    docker compose up -d --build
    print_success "重新构建完成"
}

# 数据库备份
backup_db() {
    BACKUP_DIR="./backups"
    mkdir -p "$BACKUP_DIR"

    BACKUP_FILE="$BACKUP_DIR/picanalysis-$(date +%Y%m%d-%H%M%S).db"

    print_info "备份数据库到: $BACKUP_FILE"
    docker compose exec backend cp /app/data/prod.db "/app/data/backup-$(date +%Y%m%d-%H%M%S).db"
    docker compose cp backend:/app/data/backup-$(date +%Y%m%d-%H%M%S).db "$BACKUP_FILE"
    print_success "数据库备份完成: $BACKUP_FILE"
}

# 数据库迁移
migrate_db() {
    print_info "运行数据库迁移..."
    docker compose exec backend npx prisma migrate deploy
    print_success "数据库迁移完成"
}

# 显示帮助信息
show_help() {
    cat << EOF
PicAnalysis Docker 部署脚本

使用方法: ./deploy.sh [command]

命令:
  start       启动所有服务 (默认)
  stop        停止所有服务
  restart     重启所有服务
  logs        查看所有日志
  logs [服务] 查看指定服务日志 (backend/frontend/rapidocr)
  status      查看服务状态
  clean       清理所有容器、卷和镜像
  rebuild     重新构建并启动服务
  backup      备份数据库
  migrate     运行数据库迁移
  help        显示此帮助信息

示例:
  ./deploy.sh              # 启动服务
  ./deploy.sh logs backend # 查看后端日志
  ./deploy.sh backup       # 备份数据库

EOF
}

# 主函数
main() {
    check_docker

    case "${1:-start}" in
        start)
            check_env
            start_services
            ;;
        stop)
            stop_services
            ;;
        restart)
            restart_services
            ;;
        logs)
            view_logs "$2"
            ;;
        status)
            view_status
            ;;
        clean)
            clean_services
            ;;
        rebuild)
            rebuild
            ;;
        backup)
            backup_db
            ;;
        migrate)
            migrate_db
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            print_error "未知命令: $1"
            show_help
            exit 1
            ;;
    esac
}

main "$@"
