#!/bin/bash

# =============================================================================
# Genex Admin Web - 部署管理脚本
# =============================================================================
#
# Docker 命令:
#   ./deploy.sh build                        仅构建 Docker 镜像
#   ./deploy.sh start                        构建并启动服务 (默认)
#   ./deploy.sh stop                         停止服务
#   ./deploy.sh restart                      重启服务
#   ./deploy.sh logs                         查看服务日志
#   ./deploy.sh status                       查看服务状态
#   ./deploy.sh clean                        清理容器和镜像
#
# Nginx + SSL 命令 (需要 root 权限):
#   sudo ./deploy.sh nginx install [domain] [email]   安装 Nginx + SSL 证书
#   sudo ./deploy.sh nginx ssl [domain] [email]        仅申请/续期 SSL 证书
#   ./deploy.sh nginx status                            查看 Nginx 状态
#   ./deploy.sh nginx reload                            重载 Nginx 配置
#
# 默认域名: admin.gogenex.cn
# 默认邮箱: admin@gogenex.cn
#
# =============================================================================

set -e

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

# 项目信息
PROJECT_NAME="genex-admin-web"
IMAGE_NAME="genex-admin-web"
CONTAINER_NAME="genex-admin-web"
DEFAULT_PORT=3000
DEFAULT_DOMAIN="admin.gogenex.cn"
DEFAULT_EMAIL="admin@gogenex.cn"

# 脚本目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# =============================================================================
# Docker 环境检查
# =============================================================================

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

    if ! docker info &> /dev/null; then
        log_error "Docker 服务未运行，请启动 Docker"
        exit 1
    fi

    log_success "Docker 检查通过"
}

# 检查 Docker Compose 是否安装
check_docker_compose() {
    if docker compose version &> /dev/null; then
        COMPOSE_CMD="docker compose"
    elif command -v docker-compose &> /dev/null; then
        COMPOSE_CMD="docker-compose"
    else
        log_error "Docker Compose 未安装"
        exit 1
    fi

    log_success "Docker Compose 检查通过 ($COMPOSE_CMD)"
}

# =============================================================================
# Docker 服务管理
# =============================================================================

# 构建镜像
build() {
    log_info "开始构建 Docker 镜像..."
    $COMPOSE_CMD build --no-cache
    log_success "镜像构建完成"
}

# 启动服务
start() {
    log_info "开始部署 Genex Admin Web..."

    # 检查端口是否被占用
    PORT=${PORT:-$DEFAULT_PORT}
    if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null 2>&1; then
        log_warn "端口 $PORT 已被占用，尝试停止旧服务..."
        stop
    fi

    # 构建并启动
    $COMPOSE_CMD up -d --build

    # 等待服务启动
    log_info "等待服务启动..."
    sleep 5

    # 检查服务状态
    if docker ps | grep -q $CONTAINER_NAME; then
        log_success "服务部署成功!"
        log_info "访问地址: http://localhost:$PORT"
        log_info "健康检查: http://localhost:$PORT/api/health"
    else
        log_error "服务启动失败，请查看日志: ./deploy.sh logs"
        exit 1
    fi
}

# 停止服务
stop() {
    log_info "停止服务..."
    $COMPOSE_CMD down
    log_success "服务已停止"
}

# 重启服务
restart() {
    log_info "重启服务..."
    stop
    start
}

# 查看日志
logs() {
    $COMPOSE_CMD logs -f
}

# 清理
clean() {
    log_info "清理容器和镜像..."

    # 停止并删除容器
    $COMPOSE_CMD down --rmi local --volumes --remove-orphans

    # 删除悬空镜像
    docker image prune -f

    log_success "清理完成"
}

# 显示状态
status() {
    log_info "服务状态:"
    docker ps -a --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
}

# =============================================================================
# Nginx + SSL 证书管理
# =============================================================================

# 安装 Nginx + SSL 证书 (完整流程)
# 流程:
#   1. 安装 nginx 和 certbot (如未安装)
#   2. 部署 HTTP 临时配置 (用于 Let's Encrypt 验证)
#   3. 使用 certbot webroot 方式申请 SSL 证书
#   4. 部署完整 HTTPS 配置 (从 nginx/ 目录读取)
#   5. 设置 certbot 自动续期定时任务
cmd_nginx_install() {
    local domain="${1:-$DEFAULT_DOMAIN}"
    local email="${2:-$DEFAULT_EMAIL}"
    local conf_file="$SCRIPT_DIR/nginx/${domain}.conf"

    log_info "为域名 $domain 安装 Nginx + Let's Encrypt SSL..."

    # 检查 HTTPS 配置模板是否存在
    if [ ! -f "$conf_file" ]; then
        log_error "Nginx 配置文件不存在: $conf_file"
        log_error "请先在 nginx/ 目录下创建 ${domain}.conf"
        log_info ""
        log_info "可以复制模板并修改:"
        log_info "  cp nginx/admin.gogenex.cn.conf nginx/${domain}.conf"
        log_info "  然后替换其中的域名和端口"
        exit 1
    fi

    # 检查 root 权限
    if [ "$EUID" -ne 0 ]; then
        log_error "需要 root 权限运行"
        log_info "用法: sudo ./deploy.sh nginx install $domain $email"
        exit 1
    fi

    echo ""
    echo "============================================"
    echo "  Nginx + SSL 安装"
    echo "============================================"
    echo "  域名:   $domain"
    echo "  邮箱:   $email"
    echo "  端口:   $DEFAULT_PORT"
    echo "  配置:   $conf_file"
    echo "============================================"
    echo ""

    # ---- 步骤 1: 安装依赖 ----
    log_info "[1/5] 检查并安装依赖..."

    if ! command -v nginx &> /dev/null; then
        log_info "正在安装 Nginx..."
        apt update && apt install -y nginx
        systemctl enable nginx
        systemctl start nginx
    fi
    log_success "Nginx 已就绪 ($(nginx -v 2>&1))"

    if ! command -v certbot &> /dev/null; then
        log_info "正在安装 Certbot..."
        apt install -y certbot python3-certbot-nginx
    fi
    log_success "Certbot 已就绪 ($(certbot --version 2>&1))"

    # ---- 步骤 2: 部署 HTTP 临时配置 ----
    log_info "[2/5] 部署 HTTP 临时配置 (用于证书验证)..."

    # 创建 certbot webroot 目录
    mkdir -p /var/www/certbot

    # 写入 HTTP-only 临时配置
    cat > /etc/nginx/sites-available/$domain << HTTPEOF
# 临时 HTTP 配置 (用于 Let's Encrypt 证书申请)
# 申请成功后将被 HTTPS 配置替换
server {
    listen 80;
    listen [::]:80;
    server_name $domain;

    # Let's Encrypt ACME 验证
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    # 临时反向代理 (证书申请前也可访问)
    location / {
        proxy_pass http://127.0.0.1:${DEFAULT_PORT};
        proxy_http_version 1.1;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
    }
}
HTTPEOF

    # 启用站点配置
    ln -sf /etc/nginx/sites-available/$domain /etc/nginx/sites-enabled/

    # 移除默认站点 (避免冲突)
    rm -f /etc/nginx/sites-enabled/default

    # 测试并重载 Nginx
    nginx -t && systemctl reload nginx
    log_success "HTTP 配置完成 (http://$domain)"

    # ---- 步骤 3: 申请 SSL 证书 ----
    log_info "[3/5] 申请 Let's Encrypt SSL 证书..."

    if [ -d "/etc/letsencrypt/live/$domain" ]; then
        log_warn "证书已存在，跳过申请"
        log_info "如需重新申请: sudo certbot certonly --force-renewal -d $domain"
    else
        echo ""
        log_warn "请确保以下条件已满足:"
        log_warn "  1. DNS A 记录 $domain 已指向本服务器 IP"
        log_warn "  2. 服务器 80 端口可从外网访问 (防火墙已放行)"
        echo ""
        read -p "确认以上条件已满足，继续申请证书? (y/n): " confirm
        if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
            log_info "已跳过证书申请，当前为 HTTP 模式"
            log_info "稍后申请证书: sudo ./deploy.sh nginx ssl $domain"
            return 0
        fi

        # 使用 webroot 方式申请证书
        certbot certonly --webroot --webroot-path=/var/www/certbot \
            --email $email --agree-tos --no-eff-email \
            -d $domain

        log_success "SSL 证书申请成功!"
    fi

    # ---- 步骤 4: 部署 HTTPS 完整配置 ----
    log_info "[4/5] 部署 HTTPS 完整配置..."

    # 从项目 nginx/ 目录复制完整 HTTPS 配置
    cp "$conf_file" /etc/nginx/sites-available/$domain

    # 测试并重载
    nginx -t && systemctl reload nginx
    log_success "HTTPS 配置已部署"

    # ---- 步骤 5: 配置自动续期 ----
    log_info "[5/5] 配置证书自动续期..."

    # certbot 安装时通常已自动配置 systemd timer 或 cron
    # 这里确保 renew hook 能正确重载 nginx
    if [ ! -f /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh ]; then
        mkdir -p /etc/letsencrypt/renewal-hooks/deploy
        cat > /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh << 'HOOKEOF'
#!/bin/bash
# Let's Encrypt 证书续期后自动重载 Nginx
systemctl reload nginx
HOOKEOF
        chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
        log_success "自动续期钩子已配置"
    else
        log_success "自动续期钩子已存在"
    fi

    # 测试续期 (dry-run)
    certbot renew --dry-run 2>/dev/null && log_success "自动续期测试通过" || log_warn "自动续期测试未通过，请检查 certbot 配置"

    # ---- 完成 ----
    echo ""
    echo "============================================"
    echo -e "  ${GREEN}Nginx + SSL 配置完成!${NC}"
    echo "============================================"
    echo ""
    echo -e "  HTTPS 访问: ${BLUE}https://$domain${NC}"
    echo -e "  HTTP 自动跳转到 HTTPS"
    echo ""
    echo "  Nginx 日志:"
    echo "    access: /var/log/nginx/${domain}.access.log"
    echo "    error:  /var/log/nginx/${domain}.error.log"
    echo ""
    echo "  证书路径:"
    echo "    cert: /etc/letsencrypt/live/$domain/fullchain.pem"
    echo "    key:  /etc/letsencrypt/live/$domain/privkey.pem"
    echo ""
    echo "  证书续期: certbot 已配置自动续期 (每天检查)"
    echo "  手动续期: sudo certbot renew"
    echo ""
}

# 仅申请/续期 SSL 证书
cmd_nginx_ssl() {
    local domain="${1:-$DEFAULT_DOMAIN}"
    local email="${2:-$DEFAULT_EMAIL}"
    local conf_file="$SCRIPT_DIR/nginx/${domain}.conf"

    # 检查 root 权限
    if [ "$EUID" -ne 0 ]; then
        log_error "需要 root 权限运行"
        log_info "用法: sudo ./deploy.sh nginx ssl $domain $email"
        exit 1
    fi

    if [ -d "/etc/letsencrypt/live/$domain" ]; then
        log_info "证书已存在，尝试续期..."
        certbot renew --cert-name $domain
        log_success "证书续期完成"
    else
        log_info "为 $domain 申请 SSL 证书..."

        # 确保 webroot 目录存在
        mkdir -p /var/www/certbot

        certbot certonly --webroot --webroot-path=/var/www/certbot \
            --email $email --agree-tos --no-eff-email \
            -d $domain

        log_success "SSL 证书申请成功!"
    fi

    # 如果 HTTPS 配置模板存在，部署它
    if [ -f "$conf_file" ]; then
        log_info "部署 HTTPS 配置..."
        cp "$conf_file" /etc/nginx/sites-available/$domain
        nginx -t && systemctl reload nginx
        log_success "HTTPS 配置已部署: https://$domain"
    else
        log_warn "HTTPS 配置模板不存在: $conf_file"
        log_warn "请手动配置 Nginx"
    fi
}

# 查看 Nginx 状态
cmd_nginx_status() {
    echo ""
    echo "============================================"
    echo "  Nginx 状态"
    echo "============================================"
    echo ""

    # Nginx 服务状态
    if systemctl is-active nginx &>/dev/null; then
        echo -e "  Nginx 服务: ${GREEN}运行中${NC}"
    else
        echo -e "  Nginx 服务: ${RED}未运行${NC}"
    fi

    # 域名配置
    echo ""
    echo "  已配置站点:"
    for conf in /etc/nginx/sites-enabled/*; do
        if [ -f "$conf" ]; then
            local name=$(basename "$conf")
            echo "    - $name"
        fi
    done

    # SSL 证书状态
    echo ""
    echo "  SSL 证书:"
    if command -v certbot &>/dev/null; then
        certbot certificates 2>/dev/null | grep -E "(Certificate Name|Expiry Date|Domains)" | sed 's/^/    /'
    else
        echo "    certbot 未安装"
    fi

    echo ""
}

# 重载 Nginx 配置
cmd_nginx_reload() {
    if [ "$EUID" -ne 0 ]; then
        log_error "需要 root 权限: sudo ./deploy.sh nginx reload"
        exit 1
    fi

    nginx -t && systemctl reload nginx
    log_success "Nginx 配置已重载"
}

# =============================================================================
# 帮助信息
# =============================================================================

show_help() {
    echo ""
    echo "Genex Admin Web 部署脚本"
    echo ""
    echo "使用方法: ./deploy.sh [命令]"
    echo ""
    echo "Docker 命令:"
    echo "  build    仅构建 Docker 镜像"
    echo "  start    构建并启动服务 (默认)"
    echo "  stop     停止服务"
    echo "  restart  重启服务"
    echo "  logs     查看服务日志"
    echo "  status   查看服务状态"
    echo "  clean    清理容器和镜像"
    echo ""
    echo "Nginx + SSL 命令:"
    echo "  nginx install [domain] [email]  安装 Nginx + Let's Encrypt SSL"
    echo "  nginx ssl [domain] [email]      申请/续期 SSL 证书"
    echo "  nginx status                    查看 Nginx 和证书状态"
    echo "  nginx reload                    重载 Nginx 配置"
    echo ""
    echo "  help     显示此帮助信息"
    echo ""
    echo "环境变量:"
    echo "  PORT     服务端口 (默认: $DEFAULT_PORT)"
    echo ""
    echo "默认配置:"
    echo "  域名: $DEFAULT_DOMAIN"
    echo "  邮箱: $DEFAULT_EMAIL"
    echo ""
    echo "示例:"
    echo "  ./deploy.sh start                              # 默认端口 3000 启动"
    echo "  PORT=8080 ./deploy.sh start                    # 指定端口 8080 启动"
    echo "  sudo ./deploy.sh nginx install                 # 安装 Nginx + SSL (默认域名)"
    echo "  sudo ./deploy.sh nginx install myapp.com a@b.c # 自定义域名和邮箱"
    echo "  sudo ./deploy.sh nginx ssl                     # 续期证书"
    echo ""
    echo "首次部署完整流程:"
    echo "  1. ./deploy.sh start                 # 启动 Docker 容器"
    echo "  2. sudo ./deploy.sh nginx install    # 安装 Nginx + SSL"
    echo "  3. 访问 https://$DEFAULT_DOMAIN"
    echo ""
}

# =============================================================================
# 主入口
# =============================================================================

main() {
    # 切换到脚本所在目录
    cd "$SCRIPT_DIR"

    # 执行命令
    case "${1:-start}" in
        build)
            check_docker
            check_docker_compose
            build
            ;;
        start)
            check_docker
            check_docker_compose
            start
            ;;
        stop)
            check_docker
            check_docker_compose
            stop
            ;;
        restart)
            check_docker
            check_docker_compose
            restart
            ;;
        logs)
            check_docker
            check_docker_compose
            logs
            ;;
        status)
            check_docker
            status
            ;;
        clean)
            check_docker
            check_docker_compose
            clean
            ;;
        nginx)
            case "${2:-install}" in
                install)
                    cmd_nginx_install "$3" "$4"
                    ;;
                ssl)
                    cmd_nginx_ssl "$3" "$4"
                    ;;
                status)
                    cmd_nginx_status
                    ;;
                reload)
                    cmd_nginx_reload
                    ;;
                *)
                    log_error "未知 nginx 命令: $2"
                    echo "用法: ./deploy.sh nginx [install|ssl|status|reload] [domain] [email]"
                    exit 1
                    ;;
            esac
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            log_error "未知命令: $1"
            show_help
            exit 1
            ;;
    esac
}

main "$@"
