#!/bin/bash
# EasyAI 一键部署脚本
# 支持交互式问答配置，兼容 IP 与域名两种访问方式
# 一行命令: git clone https://git.51easyai.com/wangbo/easyai && cd easyai && chmod +x ./start.sh && ./start.sh

set -e

# 仅配置模式（验证用）：DEPLOY_DRY_RUN=1 只生成配置文件，不执行 Docker 安装和启动
DEPLOY_DRY_RUN="${DEPLOY_DRY_RUN:-0}"

# ==================== 项目初始化 ====================
init_project_dir() {
    local script_source
    script_source="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
    if [ -f "${script_source}/docker-compose.yml" ]; then
        echo "📁 项目目录: ${script_source}"
        cd "$script_source"
        return 0
    fi
    echo "❌ 未找到 docker-compose.yml，请在 easyai 项目目录下运行 start.sh"
    echo "   启动命令: git clone https://git.51easyai.com/wangbo/easyai && cd easyai && chmod +x ./start.sh && ./start.sh"
    exit 1
}

# ==================== 配置变量（支持环境变量非交互模式） ====================
DEPLOY_MODE=""      # ip | domain
DEPLOY_IP=""
DEPLOY_DOMAIN=""
DEPLOY_HTTPS=false

sanitize_domain() {
    local domain="$1"
    domain="${domain#http://}"
    domain="${domain#https://}"
    domain="${domain%%/*}"
    domain="${domain%;}"
    echo "$domain"
}

validate_domain() {
    local domain="$1"
    # 基础域名校验：仅允许字母、数字、连字符和点；必须包含至少一个点；不能以点或连字符开头结尾
    if [[ ! "$domain" =~ ^[A-Za-z0-9.-]+$ ]]; then
        return 1
    fi
    if [[ "$domain" != *.* ]]; then
        return 1
    fi
    if [[ "$domain" =~ ^[.-] || "$domain" =~ [.-]$ ]]; then
        return 1
    fi
    if [[ "$domain" == *".."* ]]; then
        return 1
    fi
    return 0
}

prompt_or_env() {
    local var_name=$1
    local prompt_text=$2
    local env_name=$3
    local default=$4

    if [ -n "${!env_name}" ]; then
        eval "$var_name=\"${!env_name}\""
        return
    fi

    if [ -n "$default" ]; then
        read -r -p "${prompt_text} [$default]: " input
        eval "$var_name=\"${input:-$default}\""
    else
        read -r -p "${prompt_text}: " input
        eval "$var_name=\"$input\""
    fi
}

run_deploy_questions() {
    echo ""
    echo "================================"
    echo "  EasyAI 部署配置（问答模式）"
    echo "================================"
    echo ""

    # 非交互模式：环境变量已完整设置则直接使用（CI/自动化部署）
    if [ -n "$DEPLOY_ACCESS" ]; then
        if [ "$DEPLOY_ACCESS" = "ip" ] && [ -n "$DEPLOY_IP" ]; then
            DEPLOY_MODE="ip"
            echo "使用环境变量: IP 模式, IP=$DEPLOY_IP"
            return
        fi
        if [ "$DEPLOY_ACCESS" = "domain" ] && [ -n "$DEPLOY_DOMAIN" ]; then
            DEPLOY_DOMAIN="$(sanitize_domain "$DEPLOY_DOMAIN")"
            if ! validate_domain "$DEPLOY_DOMAIN"; then
                echo "❌ 环境变量 DEPLOY_DOMAIN 格式不合法: ${DEPLOY_DOMAIN}"
                exit 1
            fi
            DEPLOY_MODE="domain"
            DEPLOY_HTTPS="${DEPLOY_HTTPS_INPUT:-false}"
            echo "使用环境变量: 域名模式, 域名=$DEPLOY_DOMAIN"
            return
        fi
    fi

    # 1. IP 或域名访问
    if [ -z "$DEPLOY_ACCESS" ]; then
        echo "1. 通过 IP 地址还是域名访问？"
        echo "   [1] IP 地址（需开放 3001、3002、3003 端口）"
        echo "   [2] 域名"
        read -r -p "请选择 [1/2]: " choice
        case "$choice" in
            1) DEPLOY_MODE="ip" ;;
            2) DEPLOY_MODE="domain" ;;
            *) echo "❌ 无效选择"; exit 1 ;;
        esac
    else
        DEPLOY_MODE="$DEPLOY_ACCESS"
    fi

    if [ "$DEPLOY_MODE" = "ip" ]; then
        # 2. 输入服务器 IP
        prompt_or_env DEPLOY_IP "2. 请输入服务器 IP 地址" "DEPLOY_IP" ""
        if [ -z "$DEPLOY_IP" ]; then
            echo "❌ IP 不能为空"
            exit 1
        fi
        echo "   请确保防火墙已放行 3001、3002、3003 端口"
    else
        # 3. 输入域名
        prompt_or_env DEPLOY_DOMAIN "3. 请输入域名（不含 https:// 前缀，如 51easyai.com）" "DEPLOY_DOMAIN" ""
        DEPLOY_DOMAIN="$(sanitize_domain "$DEPLOY_DOMAIN")"
        if [ -z "$DEPLOY_DOMAIN" ]; then
            echo "❌ 域名不能为空"
            exit 1
        fi
        if ! validate_domain "$DEPLOY_DOMAIN"; then
            echo "❌ 域名格式不合法: ${DEPLOY_DOMAIN}"
            echo "   请输入类似 51easyai.com 的域名，不要包含协议、路径或分号"
            exit 1
        fi

        # 3.1 是否启用 HTTPS
        if [ -n "$DEPLOY_HTTPS_INPUT" ]; then
            DEPLOY_HTTPS=$DEPLOY_HTTPS_INPUT
        else
            read -r -p "3.1 是否启用 HTTPS？[y/N]: " https_choice
            DEPLOY_HTTPS=false
            if [[ "$https_choice" =~ ^[yY] ]]; then
                DEPLOY_HTTPS=true
            fi
        fi
        if [ "$DEPLOY_HTTPS" = true ]; then
            echo "   启用 HTTPS 需确保防火墙已放行 80、443 端口"
        fi
    fi
}

# ==================== 生成配置文件 ====================
setup_env_files() {
    echo ""
    echo "📝 配置环境文件..."

    # 6. 复制 .env.tools、.env.ASG、.env.AMS（无 example 后缀的从 .sample 生成）
    if [ ! -f .env.tools ]; then
        cp .env.tools.sample .env.tools
        echo "   ✓ .env.tools"
    fi
    if [ ! -f .env.ASG ]; then
        cp .env.ASG.sample .env.ASG
        echo "   ✓ .env.ASG"
    fi
    if [ ! -f .env.AMS ]; then
        cp .env.AMS.sample .env.AMS
        echo "   ✓ .env.AMS"
    fi

    # 4/5. 配置 .env
    if [ ! -f .env ]; then
        cp .env.sample .env
    fi

    if [ "$DEPLOY_MODE" = "ip" ]; then
        # IP 模式
        sed -i.bak "s|^NUXT_PUBLIC_BASE_APIURL=.*|NUXT_PUBLIC_BASE_APIURL=http://${DEPLOY_IP}:3001|" .env
        sed -i.bak "s|^NUXT_PUBLIC_BASE_SOCKETURL=.*|NUXT_PUBLIC_BASE_SOCKETURL=ws://${DEPLOY_IP}:3002|" .env
        sed -i.bak "s|^NUXT_PUBLIC_SG_APIURL=.*|NUXT_PUBLIC_SG_APIURL=http://${DEPLOY_IP}:3003|" .env
        echo "   ✓ .env 已配置为 IP 模式 (${DEPLOY_IP})"
    else
        # 域名模式
        sed -i.bak "s|^NUXT_PUBLIC_BASE_APIURL=.*|NUXT_PUBLIC_BASE_APIURL=/api|" .env
        sed -i.bak "s|^NUXT_PUBLIC_BASE_SOCKETURL=.*|NUXT_PUBLIC_BASE_SOCKETURL=wss://${DEPLOY_DOMAIN}/socket.io|" .env
        sed -i.bak "s|^NUXT_PUBLIC_SG_APIURL=.*|NUXT_PUBLIC_SG_APIURL=/asg-api|" .env
        echo "   ✓ .env 已配置为域名模式 (${DEPLOY_DOMAIN})"

        # 7. Nginx 配置（域名模式）
        PROXY_CONF="${DEPLOY_DOMAIN}.conf"
        if [ ! -f "$PROXY_CONF" ]; then
            sed "s/51easyai.com/${DEPLOY_DOMAIN}/g" easyai-proxy.conf.sample > "$PROXY_CONF"
            echo "   ✓ Nginx 配置已生成: $PROXY_CONF"
        fi
    fi

    rm -f .env.bak
}

# ==================== Docker 安装（复用原 start.sh 逻辑） ====================
install_docker() {
    echo ""
    echo "================================"
    echo "  Docker 安装与检查"
    echo "================================"

    if [ -f /etc/os-release ]; then
        . /etc/os-release
        case "${ID:-}" in
            ubuntu|debian) OS_FAMILY="Ubuntu" ;;
            centos|rhel|fedora) OS_FAMILY="CentOS" ;;
            *) OS_FAMILY="${ID:-Unknown}" ;;
        esac
    else
        OS_FAMILY=$(hostnamectl 2>/dev/null | grep "Operating System" | awk '{print $3}' || echo "Unknown")
    fi
    OS_VERSION_ID=$(grep -oP '(?<=^VERSION_ID=")[0-9.]+' /etc/os-release 2>/dev/null | cut -d'.' -f1 || echo "0")
    OS_CODENAME=""
    if [[ "$OS_FAMILY" == "Ubuntu" ]]; then
        OS_CODENAME=$(lsb_release -cs 2>/dev/null || (grep VERSION_CODENAME /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d '"'))
    fi

    UBUNTU_DOCKER_MIRROR_URL="https://mirrors.ustc.edu.cn/docker-ce"
    UBUNTU_DOCKER_GPG_URL="https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg"
    CENTOS_DOCKER_MIRROR_URL="https://mirrors.tuna.tsinghua.edu.cn/docker-ce"

    check_network() {
        if curl -sSf --connect-timeout 5 https://download.docker.com/ &>/dev/null; then
            echo "✅ 网络连接正常"
            return 0
        fi
        echo "⚠️ 将使用国内镜像源"
        return 0
    }
    check_network

    if command -v docker &>/dev/null; then
        echo "✅ Docker 已安装"
    else
        if [[ "$OS_FAMILY" == "Ubuntu" ]]; then
            sudo apt update -y
            sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
            sudo install -m 0755 -d /etc/apt/keyrings
            curl -fsSL "$UBUNTU_DOCKER_GPG_URL" | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg 2>/dev/null || \
                curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
            sudo chmod a+r /etc/apt/keyrings/docker.gpg
            echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] $UBUNTU_DOCKER_MIRROR_URL/linux/ubuntu $OS_CODENAME stable" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
            sudo apt-get update -y
            sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
        elif [[ "$OS_FAMILY" == "CentOS" ]]; then
            sudo yum install -y yum-utils
            sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
            sudo sed -i "s+https://download.docker.com+$CENTOS_DOCKER_MIRROR_URL+g" /etc/yum.repos.d/docker-ce.repo
            [[ "$OS_VERSION_ID" -ge "8" ]] && sudo yum module disable -y container-tools 2>/dev/null || true
            sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
        else
            echo "❌ 不支持的操作系统: $OS_FAMILY"
            exit 1
        fi
        sudo systemctl enable docker
        sudo systemctl start docker
        getent group docker | grep -qw "$USER" || sudo usermod -aG docker "$USER"
    fi

    if docker compose version &>/dev/null; then
        echo "✅ Docker Compose 已就绪"
    elif command -v docker-compose &>/dev/null; then
        echo "✅ Docker Compose (兼容模式) 已就绪"
    else
        echo "❌ 请安装 docker-compose-plugin"
        exit 1
    fi
}

# ==================== 启动服务 ====================
start_services() {
    echo ""
    echo "🚀 启动 EasyAI 服务..."
    if docker compose version &>/dev/null; then
        sudo docker compose pull && sudo docker compose up -d
    else
        sudo docker-compose pull && sudo docker-compose up -d
    fi
    echo "🎉 EasyAI 应用启动成功"
}

# ==================== 执行 HTTPS 配置 ====================
run_https_setup() {
    if [ "$DEPLOY_HTTPS" = true ] && [ -n "$DEPLOY_DOMAIN" ]; then
        echo ""
        echo "🔒 执行 HTTPS 配置（请确保服务器已放行 80、443 端口）..."
        if [ -f "./https.sh" ]; then
            # https.sh 依赖 easyai-proxy.conf，需使用生成的域名配置文件
            export EASYAI_PROXY_CONF="${DEPLOY_DOMAIN}.conf"
            bash ./https.sh
        else
            echo "⚠️ 未找到 https.sh，请手动配置 HTTPS"
        fi
    fi
}

# ==================== 主流程 ====================
main() {
    init_project_dir

    # 检查是否已有 .env 且非强制重新配置
    if [ -f .env ] && [ -z "$DEPLOY_FORCE_RECONFIG" ] && [ -z "$DEPLOY_ACCESS" ]; then
        echo "📁 检测到已有 .env 配置"
        read -r -p "是否重新配置部署方式？[y/N]: " reconfigure
        if [[ ! "$reconfigure" =~ ^[yY] ]]; then
            echo "⏭️ 使用现有配置继续..."
            DEPLOY_MODE="skip"
        fi
    fi

    if [ "$DEPLOY_MODE" != "skip" ]; then
        run_deploy_questions
    fi

    if [ "$DEPLOY_MODE" != "skip" ]; then
        setup_env_files
    else
        if [ ! -f .env.tools ]; then
            cp .env.tools.sample .env.tools
        fi
        if [ ! -f .env.ASG ]; then
            cp .env.ASG.sample .env.ASG
        fi
        if [ ! -f .env.AMS ]; then
            cp .env.AMS.sample .env.AMS
        fi
    fi

    if [ "$DEPLOY_DRY_RUN" = "1" ]; then
        echo ""
        echo "⚠️  dry-run 模式：跳过 Docker 安装和服务启动"
        echo "   配置文件已生成，可直接运行 ./start.sh 完成部署"
    else
        install_docker
        start_services
        run_https_setup
    fi

    echo ""
    echo "================================"
    echo "  部署完成"
    echo "================================"
    if [ "$DEPLOY_MODE" = "ip" ] && [ -n "$DEPLOY_IP" ]; then
        echo "访问地址: http://${DEPLOY_IP}:3010"
    elif [ "$DEPLOY_MODE" = "domain" ] && [ -n "$DEPLOY_DOMAIN" ]; then
        echo "访问地址: http://${DEPLOY_DOMAIN} (配置 Nginx 后)"
        if [ "$DEPLOY_HTTPS" = true ]; then
            echo "HTTPS 已启用"
        fi
    fi
    echo ""
}

main "$@"
