#!/bin/bash
# ===========================================================================
# 茗管家 ZenTea ERP 客户端一键自动化安装与部署脚本
# 适用宿主机系统：Ubuntu 20/22/24, CentOS 7/8/9
# ===========================================================================

set -Eeuo pipefail
umask 077

# 云端授权中心 API 与一键分发站配置（可根据实际部署域名进行替换）
LICENSE_SERVER_URL="https://api.zenteaerp.com"
DEPLOY_SERVER_URL="https://deploy.zenteaerp.com"

echo "==========================================================================="
# 统一使用“茗管家”，不使用“茗掌柜”
echo "       欢迎使用 茗管家 ZenTea ERP 一键自动化安装程序"
echo "==========================================================================="

# 必须使用 root 权限执行此脚本
if [ "$EUID" -ne 0 ]; then
    echo "[ERROR] 请使用 root 权限（或 sudo）执行此脚本！"
    echo '标准安装命令: curl -fsSL https://deploy.zenteaerp.com/install.sh -o /tmp/zentea-install.sh && echo "$(curl -fsSL https://api.zenteaerp.com/api/v1/releases/installer-sha256)  /tmp/zentea-install.sh" | sha256sum -c - && sudo bash /tmp/zentea-install.sh'
    exit 1
fi

# ==========================================
# 1. 参数解析与校验
# ==========================================
LICENSE_KEY="${ZENTEA_LICENSE_KEY:-}"
REPAIR_UPGRADER=false
TEMP_DIR=$(mktemp -d -t zentea-install.XXXXXX)
LICENSE_RESPONSE="$TEMP_DIR/license-response.json"
NGINX_SETUP="/opt/zentea/client_setup_nginx.sh"

cleanup() {
    unset LICENSE_KEY DOCKER_PASS SECRET_KEY_VAL BACKUP_KEY DB_PASSWORD REDIS_PASSWORD_VAL ADMIN_PASSWORD
    rm -rf "$TEMP_DIR"
}
trap cleanup EXIT INT TERM HUP

# 解析命令行参数
while [ "$#" -gt 0 ]; do
    case "$1" in
        --license-key=*)
            LICENSE_KEY="${1#*=}"
            shift
            ;;
        --repair-upgrader)
            REPAIR_UPGRADER=true
            shift
            ;;
        *)
            echo "[ERROR] 未知参数: $1"
            echo "用法: bash install.sh [--repair-upgrader] [--license-key=\"CLIENT_LICENSE_KEY\"]"
            exit 1
            ;;
    esac
done

if [ -z "$LICENSE_KEY" ]; then
    if [ -c /dev/tty ]; then
        read -r -s -p "请输入授权码: " LICENSE_KEY </dev/tty
        echo "" >/dev/tty
    else
        echo "[ERROR] 当前环境无法安全读取授权码，请设置临时环境变量 ZENTEA_LICENSE_KEY 后重试。"
        exit 1
    fi
fi

if [[ ! "$LICENSE_KEY" =~ ^ZT-[A-Za-z0-9-]{8,128}$ ]]; then
    echo "[ERROR] 授权码格式无效。"
    exit 1
fi

echo "[INFO] 正在向授权中心安全校验授权信息..."

# 2. 联网向云端校验 License 合法性，并获取基本信息
HTTP_RESP=$(printf '{"license_key":"%s","product_code":"zentea","current_version":"0.0.0"}' "$LICENSE_KEY" | curl -sS -X POST -w "%{http_code}" \
    -H "Content-Type: application/json" \
    --data-binary @- \
    "${LICENSE_SERVER_URL}/api/v1/releases/latest" -o "$LICENSE_RESPONSE" || true)

if [ "$HTTP_RESP" != "200" ]; then
    echo "[ERROR] 授权密钥校验失败 (HTTP STATUS: $HTTP_RESP)！请确保网络畅通且 License Key 有效。"
    exit 1
fi

# 检查云端是否返回了合法更新版本（使用 Python 3 进行防呆解析，完全兼容单/多介质）
LATEST_VERSION=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); print(data.get('latest_version', ''))" 2>/dev/null || true)
BACKEND_IMAGE_PATH=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); arts=data.get('artifacts') or []; art=next((a for a in arts if a.get('artifact_type')=='backend_docker_image'), data.get('artifact') or {}); print(art.get('artifact_path', ''))" 2>/dev/null || true)
BACKEND_IMAGE_DIGEST=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); arts=data.get('artifacts') or []; art=next((a for a in arts if a.get('artifact_type')=='backend_docker_image'), data.get('artifact') or {}); print(art.get('artifact_digest', ''))" 2>/dev/null || true)
FRONTEND_IMAGE_PATH=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); arts=data.get('artifacts') or []; art=next((a for a in arts if a.get('artifact_type')=='frontend_docker_image'), {}); print(art.get('artifact_path', ''))" 2>/dev/null || true)
FRONTEND_IMAGE_DIGEST=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); arts=data.get('artifacts') or []; art=next((a for a in arts if a.get('artifact_type')=='frontend_docker_image'), {}); print(art.get('artifact_digest', ''))" 2>/dev/null || true)
UPGRADE_PUBLIC_KEY_SHA256=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); print((data.get('client_artifacts') or {}).get('upgrade_public_key', ''))" 2>/dev/null || true)
UPGRADER_SHA256=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); print((data.get('client_artifacts') or {}).get('upgrader', ''))" 2>/dev/null || true)
COMPOSE_SHA256=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); print((data.get('client_artifacts') or {}).get('compose', ''))" 2>/dev/null || true)
NGINX_SETUP_SHA256=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); print((data.get('client_artifacts') or {}).get('nginx_setup', ''))" 2>/dev/null || true)
INSTALLER_SHA256=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); print((data.get('client_artifacts') or {}).get('installer', ''))" 2>/dev/null || true)

for digest in "$UPGRADE_PUBLIC_KEY_SHA256" "$UPGRADER_SHA256" "$COMPOSE_SHA256" "$NGINX_SETUP_SHA256" "$INSTALLER_SHA256"; do
    if [[ ! "$digest" =~ ^[0-9a-fA-F]{64}$ ]]; then
        echo "[ERROR] 授权中心未返回完整的客户安装介质摘要，已安全停止安装。"
        exit 1
    fi
done

if [ -f "$0" ]; then
    echo "${INSTALLER_SHA256}  $0" | sha256sum -c - >/dev/null || {
        echo "[ERROR] 安装脚本摘要与授权中心记录不一致，已拒绝继续执行。"
        exit 1
    }
else
    echo "[ERROR] 管道执行无法校验安装脚本自身，已拒绝继续。"
    echo '请改用: curl -fsSL https://deploy.zenteaerp.com/install.sh -o /tmp/zentea-install.sh && echo "$(curl -fsSL https://api.zenteaerp.com/api/v1/releases/installer-sha256)  /tmp/zentea-install.sh" | sha256sum -c - && sudo bash /tmp/zentea-install.sh'
    exit 1
fi

download_verified() {
    local url="$1"
    local destination="$2"
    local expected_sha256="$3"
    local staged="$TEMP_DIR/$(basename "$destination").download"
    curl -fsSL "$url" -o "$staged" || {
        echo "[ERROR] 下载客户安装介质失败: $url"
        return 1
    }
    echo "${expected_sha256}  ${staged}" | sha256sum -c - >/dev/null || {
        echo "[ERROR] 客户安装介质摘要校验失败: $url"
        return 1
    }
    install -m 0755 "$staged" "$destination"
}

repair_existing_upgrader() {
    local docker_user docker_pass registry_host registry_file compose_file compose_backup zentea_gid

    echo "[INFO] 正在无损修复现有客户机的在线升级组件..."
    [ -f /etc/zentea-upgrader/config.yaml ] || {
        echo "[ERROR] 未检测到现有 upgrader 配置；请使用全新安装流程。"
        exit 1
    }
    [ -f /etc/systemd/system/zentea-upgrader.service ] || {
        echo "[ERROR] 未检测到现有 upgrader systemd 服务；请使用全新安装流程。"
        exit 1
    }

    docker_user=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); print(data.get('docker_username', ''))" 2>/dev/null || true)
    docker_pass=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); print(data.get('docker_password', ''))" 2>/dev/null || true)
    registry_host=$(echo "$BACKEND_IMAGE_PATH" | cut -d/ -f1)
    if [ -z "$docker_user" ] || [ -z "$docker_pass" ] || [ -z "$registry_host" ]; then
        echo "[ERROR] 授权中心未返回完整的私有镜像仓库只读凭据，已停止修复。"
        exit 1
    fi

    install -d -m 0755 /etc/zentea-upgrader /opt/zentea-upgrader
    download_verified "${DEPLOY_SERVER_URL}/static/keys/public.pem?v=${UPGRADE_PUBLIC_KEY_SHA256}" /etc/zentea-upgrader/official_public_key.pem "$UPGRADE_PUBLIC_KEY_SHA256"
    chmod 0644 /etc/zentea-upgrader/official_public_key.pem
    download_verified "${DEPLOY_SERVER_URL}/static/scripts/upgrader.py" /opt/zentea-upgrader/upgrader.py "$UPGRADER_SHA256"
    python3 -m py_compile /opt/zentea-upgrader/upgrader.py

    if ! grep -q '^registry_auth_file:' /etc/zentea-upgrader/config.yaml; then
        printf '\nregistry_auth_file: "/etc/zentea-upgrader/registry.env"\n' >> /etc/zentea-upgrader/config.yaml
    fi
    if ! grep -q '^migration_timeout_seconds:' /etc/zentea-upgrader/config.yaml; then
        printf 'migration_timeout_seconds: 300\n' >> /etc/zentea-upgrader/config.yaml
    fi

    registry_file="$TEMP_DIR/registry.env"
    printf 'REGISTRY_HOST=%s\nREGISTRY_USERNAME=%s\nREGISTRY_PASSWORD=%s\n' \
        "$registry_host" "$docker_user" "$docker_pass" > "$registry_file"
    install -m 0600 "$registry_file" /etc/zentea-upgrader/registry.env

    compose_file="/opt/zentea/docker-compose.yml"
    env_file="/opt/zentea/.env"
    if [ -f "$env_file" ]; then
        chown root:root "$env_file"
        chmod 0600 "$env_file"
    fi
    [ -f "$compose_file" ] || {
        echo "[ERROR] 未检测到现有 ZenTea Compose 文件: $compose_file"
        exit 1
    }
    zentea_gid=$(getent group zentea | cut -d: -f3 || true)
    [ -n "$zentea_gid" ] || {
        echo "[ERROR] 未检测到宿主机 zentea 用户组，无法安全授予 backend UDS 权限。"
        exit 1
    }
    python3 -c "import yaml" >/dev/null 2>&1 || {
        echo "[ERROR] 缺少 python3-yaml，无法安全修补旧版 Compose。"
        exit 1
    }

    compose_backup="${compose_file}.before-upgrader-repair.$(date +%Y%m%d%H%M%S)"
    cp -a "$compose_file" "$compose_backup"
    python3 - "$compose_file" "$zentea_gid" <<'PY'
import os
import sys
from pathlib import Path

import yaml

path = Path(sys.argv[1])
gid = str(sys.argv[2])
data = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
services = data.setdefault("services", {})
backend = services.get("backend")
if not isinstance(backend, dict):
    raise SystemExit("Compose 中缺少 backend 服务")

groups = [str(item) for item in (backend.get("group_add") or [])]
if gid not in groups:
    groups.append(gid)
backend["group_add"] = groups

volumes = list(backend.get("volumes") or [])
if not any("/run/zentea-upgrader" in str(item) for item in volumes):
    volumes.append("/run/zentea-upgrader:/run/zentea-upgrader")
backend["volumes"] = volumes
backend["read_only"] = True
backend["tmpfs"] = ["/tmp:rw,noexec,nosuid,nodev,size=64m"]
security_opt = [str(item) for item in (backend.get("security_opt") or [])]
if "no-new-privileges:true" not in security_opt:
    security_opt.append("no-new-privileges:true")
backend["security_opt"] = security_opt
cap_drop = [str(item) for item in (backend.get("cap_drop") or [])]
if "ALL" not in cap_drop:
    cap_drop.append("ALL")
backend["cap_drop"] = cap_drop

tmp = path.with_suffix(path.suffix + ".repair.tmp")
tmp.write_text(yaml.safe_dump(data, allow_unicode=True, sort_keys=False), encoding="utf-8")
os.replace(tmp, path)
PY
    if ! docker compose -f "$compose_file" config --quiet; then
        cp -a "$compose_backup" "$compose_file"
        echo "[ERROR] 修补后的 Compose 校验失败，已恢复原文件: $compose_backup"
        exit 1
    fi

    systemctl restart zentea-upgrader.service
    systemctl is-active --quiet zentea-upgrader.service || {
        echo "[ERROR] upgrader 服务重启失败，请执行 journalctl -u zentea-upgrader -n 100 查看原因。"
        exit 1
    }

    docker compose -f "$compose_file" up -d --no-deps --force-recreate backend
    if ! docker exec zentea-backend sh -c "id -G | tr ' ' '\n' | grep -qx '$zentea_gid'"; then
        echo "[ERROR] backend 重建后仍未加入 zentea GID $zentea_gid，请检查 Compose 与 Docker 日志。"
        exit 1
    fi
    docker exec zentea-backend test -S /run/zentea-upgrader/upgrader.sock || {
        echo "[ERROR] backend 容器内仍无法访问 upgrader socket。"
        exit 1
    }

    echo "[OK] 在线升级组件修复完成。已备份并仅补齐旧版 Compose 的 UDS 权限配置。"
    echo "未修改数据库、ZenTea .env、系统密钥、备份密钥或管理员账号。"
    echo "请返回 ZenTea PC 后台重新执行系统升级。"
}

if [ "$REPAIR_UPGRADER" = "true" ]; then
    repair_existing_upgrader
    exit 0
fi

image_ref() {
    local image_path="${1:-}"
    local image_digest="${2:-}"
    if [[ "$image_digest" == *@sha256:* ]]; then
        echo "$image_digest"
        return
    fi
    if [[ "$image_path" == *@sha256:* ]]; then
        echo "$image_path"
        return
    fi
    if [ -n "$image_path" ] && [ -n "$image_digest" ]; then
        local image_repo="$image_path"
        local last_part="${image_repo##*/}"
        if [[ "$last_part" == *:* ]]; then
            image_repo="${image_repo%:*}"
        fi
        echo "${image_repo}@${image_digest}"
    else
        echo "$image_path"
    fi
}

if [ -z "$LATEST_VERSION" ] || [ -z "$BACKEND_IMAGE_PATH" ]; then
    echo "[ERROR] 授权中心未能返回合法的基础发布版本介质，请联系系统供应商确认版本状态。"
    exit 1
fi

echo "[OK] 授权校验成功！"
echo "  - 授权激活版本: $LATEST_VERSION"
echo "  - 后端镜像路径: $BACKEND_IMAGE_PATH"
if [ -n "$FRONTEND_IMAGE_PATH" ]; then
    echo "  - 前端镜像路径: $FRONTEND_IMAGE_PATH"
else
    echo "  - 前端镜像路径: 未返回，安装将使用 compose 模板默认前端镜像"
fi
# ==========================================
# 3. 宿主机基础依赖与 Docker 环境自动检测/安装
# ==========================================
echo "[INFO] 正在检测并安装系统基础依赖及 Docker 环境..."

# 检测系统类型
if [ -f /etc/redhat-release ]; then
    OS="centos"
elif [ -f /etc/lsb-release ] || [ -f /etc/debian_version ]; then
    OS="ubuntu"
else
    echo "[ERROR] 本脚本暂不支持该操作系统类型，请手动安装 Docker / Python 3 后运行。"
    exit 1
fi

wait_for_package_manager() {
    if [ "$OS" != "ubuntu" ]; then
        return 0
    fi
    local waited=0
    local max_wait="${ZENTEA_APT_LOCK_TIMEOUT:-900}"
    if [[ ! "$max_wait" =~ ^[0-9]+$ ]] || [ "$max_wait" -lt 60 ]; then
        max_wait=900
    fi
    while fuser /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock /var/cache/apt/archives/lock >/dev/null 2>&1; do
        if [ "$waited" -ge "$max_wait" ]; then
            echo "[ERROR] apt/dpkg 锁在 ${max_wait} 秒内未释放，占用进程如下："
            fuser -v /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock /var/cache/apt/archives/lock 2>&1 | sed 's/^/       /' || true
            echo "[ERROR] 请等待系统自动更新完成后重新执行安装命令，禁止删除锁文件或强制终止 dpkg。"
            return 1
        fi
        echo "[INFO] 系统正在自动更新软件包，等待 apt/dpkg 锁释放... (${waited}s)"
        if [ $((waited % 30)) -eq 0 ]; then
            echo "[INFO] 当前 apt/dpkg 锁占用进程："
            fuser -v /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock /var/cache/apt/archives/lock 2>&1 | sed 's/^/       /' || true
        fi
        sleep 5
        waited=$((waited + 5))
    done
}

remove_docker_apt_source() {
    rm -f /etc/apt/sources.list.d/docker.list
}

install_ubuntu_docker_from_official_repo() {
    local codename
    codename="$(. /etc/os-release && printf '%s' "${UBUNTU_CODENAME:-${VERSION_CODENAME:-}}")"
    if [ -z "$codename" ]; then
        echo "[WARN] 无法识别 Ubuntu 发行版代号，跳过 Docker 官方软件源。"
        return 1
    fi

    echo "[INFO] 正在配置 Docker 官方软件源..."
    install -m 0755 -d /etc/apt/keyrings
    rm -f /etc/apt/keyrings/docker.asc
    if ! curl -fsSL --retry 3 --connect-timeout 10 --max-time 60 \
        https://download.docker.com/linux/ubuntu/gpg \
        -o /etc/apt/keyrings/docker.asc; then
        echo "[ERROR] Docker 官方签名密钥下载失败，且 Ubuntu 系统 Docker 软件包不可用。"
        remove_docker_apt_source
        return 1
    fi
    chmod a+r /etc/apt/keyrings/docker.asc
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $codename stable" \
        > /etc/apt/sources.list.d/docker.list

    wait_for_package_manager
    if ! apt-get \
        -o Acquire::Retries=2 \
        -o Acquire::http::Timeout=20 \
        -o Acquire::https::Timeout=20 \
        update; then
        echo "[ERROR] Docker 官方软件源不可用，且 Ubuntu 系统 Docker 软件包不可用。"
        remove_docker_apt_source
        wait_for_package_manager
        apt-get update
        return 1
    fi

    wait_for_package_manager
    if ! apt-get \
        -o Acquire::Retries=2 \
        -o Acquire::http::Timeout=20 \
        -o Acquire::https::Timeout=20 \
        install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin; then
        echo "[ERROR] Docker CE 安装失败，且 Ubuntu 系统 Docker 软件包不可用。"
        remove_docker_apt_source
        wait_for_package_manager
        apt-get update
        return 1
    fi
}

install_ubuntu_docker_from_distribution() {
    echo "[INFO] 正在使用 Ubuntu 系统软件源安装 Docker..."
    remove_docker_apt_source
    wait_for_package_manager
    apt-get update
    if ! apt-cache show docker.io docker-compose-v2 >/dev/null 2>&1; then
        echo "[WARN] 当前 Ubuntu 版本未提供 Docker Compose v2，将尝试 Docker 官方软件源。"
        return 1
    fi
    wait_for_package_manager
    if ! apt-get install -y docker.io docker-compose-v2; then
        echo "[WARN] Ubuntu 系统 Docker 软件包安装失败，将尝试 Docker 官方软件源。"
        return 1
    fi
}

# 安装 Docker 与 Curl / Python 3
if ! command -v docker &> /dev/null; then
    echo "[INFO] 正在安装 Docker 引擎..."
    if [ "$OS" == "centos" ]; then
        yum install -y yum-utils
        yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
        yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
    else
        # 清理旧安装器可能遗留的失效 Docker APT 源，避免首次 apt update 直接失败。
        remove_docker_apt_source
        wait_for_package_manager
        apt-get update
        wait_for_package_manager
        apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release python3
        if ! install_ubuntu_docker_from_distribution; then
            install_ubuntu_docker_from_official_repo
        fi
    fi
    systemctl enable docker
    systemctl start docker
fi

if ! command -v docker >/dev/null 2>&1 || ! docker compose version >/dev/null 2>&1; then
    echo "[ERROR] Docker 或 Docker Compose v2 安装不完整，无法继续部署 ZenTea。"
    exit 1
fi

# 安装 python 依赖 (cryptography 与 PyYAML)
echo "[INFO] 正在安装守护进程 Python3 基础依赖..."
if [ "$OS" == "centos" ]; then
    yum install -y python3-pip python3-cryptography python3-yaml || true
else
    wait_for_package_manager
    apt-get update
    wait_for_package_manager
    apt-get install -y python3-pip python3-cryptography python3-yaml || true
fi

# 创建运行目录与系统用户组
sudo groupadd zentea 2>/dev/null || true
sudo mkdir -p /etc/zentea-upgrader /opt/zentea-upgrader /var/lib/zentea-upgrader/backups /run/zentea-upgrader
sudo chmod 770 /run/zentea-upgrader
sudo chown -R root:zentea /run/zentea-upgrader

# ==========================================
# 4. 下载升级守护进程代码与公钥证书
# ==========================================
echo "[INFO] 正在下载系统安全证书与守护进程程序..."

# 摘要来自授权 API，文件来自独立分发站；任一单点被篡改都会校验失败。
download_verified "${DEPLOY_SERVER_URL}/static/keys/public.pem?v=${UPGRADE_PUBLIC_KEY_SHA256}" /etc/zentea-upgrader/official_public_key.pem "$UPGRADE_PUBLIC_KEY_SHA256"
chmod 0644 /etc/zentea-upgrader/official_public_key.pem
download_verified "${DEPLOY_SERVER_URL}/static/scripts/upgrader.py" /opt/zentea-upgrader/upgrader.py "$UPGRADER_SHA256"

# ==========================================
# 5. 生成强数据库密码凭证与本地配置文件
# ==========================================
echo "[INFO] 正在生成本地高安全数据库隔离凭证与升级配置..."

DB_PASSWORD=""

# 如果先前已安装过，优先保留并提取原有的数据库连接密码，绝不覆盖
if [ -f /etc/zentea-upgrader/db.env ]; then
    DB_PASSWORD=$(grep '^POSTGRES_PASSWORD=' /etc/zentea-upgrader/db.env | cut -d'=' -f2-)
fi

# 如果是首次安装，则随机生成
if [ -z "$DB_PASSWORD" ]; then
    DB_PASSWORD=$(openssl rand -hex 24)
fi

# 写入 db.env 并限定 0600 特权权限
cat > /etc/zentea-upgrader/db.env << EOF
POSTGRES_USER=postgres
POSTGRES_PASSWORD=${DB_PASSWORD}
POSTGRES_DB=zentea_db
POSTGRES_SERVER=zentea-db
POSTGRES_PORT=5432
EOF
chmod 0600 /etc/zentea-upgrader/db.env

# 写入 config.yaml 升级配置文件
cat > /etc/zentea-upgrader/config.yaml << EOF
compose_file: "/opt/zentea/docker-compose.yml"
compose_project: "zentea"
backend_service: "backend"
backend_image_env_key: "ZENTEA_BACKEND_IMAGE"
frontend_service: "frontend"
frontend_image_env_key: "ZENTEA_FRONTEND_IMAGE"
health_check_url: "http://localhost:8000/api/v1/health"
docker_network: "zentea-network"
db_container: "zentea-db"
backup_dir: "/var/lib/zentea-upgrader/backups"
# 在线升级始终在此目录保存 PostgreSQL 本地安全快照；若 ZenTea 后台配置了 OSS，
# 后端会在触发 upgrader 前先完成包含数据库与 uploads/附件的全量云备份。
compose_env_file: "/opt/zentea/.env"
registry_auth_file: "/etc/zentea-upgrader/registry.env"
migration_timeout_seconds: 300
EOF

# ==========================================
# 6. 注册并拉起 Systemd 升级守护进程服务
# ==========================================
echo "[INFO] 正在注册并运行系统后台升级守护进程 (zentea-upgrader)..."

cat > /etc/systemd/system/zentea-upgrader.service << EOF
[Unit]
Description=ZenTea ERP Safe Online Upgrader Daemon
After=network.target docker.service
Requires=docker.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/zentea-upgrader
ExecStart=/usr/bin/python3 /opt/zentea-upgrader/upgrader.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now zentea-upgrader.service

# ==========================================
# 7. 首次一键拉起 ERP 容器系统
# ==========================================
echo "[INFO] 正在拉取最新的 茗管家 ERP 系统镜像并首次部署运行..."

sudo mkdir -p /opt/zentea
ZENTEA_GID=$(getent group zentea | cut -d: -f3 || echo "1001")

# 正式商用后端只接受真实 HTTPS 域名。历史 HTTP 单机/局域网模式与
# ENV=production 的 CORS/TrustedHost 安全合同冲突，明确禁用，不再向客户提供。
# CORS_ORIGINS="[\"*\"]"
# BIND_HOST="0.0.0.0"
# DEPLOY_MODE="lan"
CORS_ORIGINS=""
BIND_HOST="127.0.0.1"
DEPLOY_MODE="public"
DOMAIN_SCHEME="1"

DOMAIN_ADMIN=""
DOMAIN_MEMBER=""
DOMAIN_TRACE=""
PUBLIC_ADMIN_DOMAIN=""
PUBLIC_MEMBER_DOMAIN=""
PUBLIC_TRACE_DOMAIN=""
NGINX_ADMIN_DOMAIN=""
NGINX_MEMBER_DOMAIN=""
NGINX_TRACE_DOMAIN=""

normalize_public_origin() {
    local raw="${1:-}"
    local host=""
    raw="${raw%/}"
    host="$(public_origin_host "$raw")"
    echo "https://$host"
}

public_origin_host() {
    local raw="${1:-}"
    raw="${raw#http://}"
    raw="${raw#https://}"
    raw="${raw%%/*}"
    echo "$raw"
}

require_public_domain() {
    local raw="${1:-}"
    local host=""
    local without_scheme=""
    without_scheme="${raw#http://}"
    without_scheme="${without_scheme#https://}"
    without_scheme="${without_scheme%/}"
    host="$(public_origin_host "$raw" | tr '[:upper:]' '[:lower:]')"
    if [[ "$without_scheme" == */* ]] || [ -z "$host" ] || [ "$host" = "localhost" ] || [[ "$host" == *.localhost ]] || \
       [[ "$host" =~ ^[0-9.]+$ ]] || [[ "$host" == *:* ]] || \
       [[ ! "$host" =~ ^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$ ]]; then
        echo "[ERROR] 必须填写可解析的公网域名，不能使用 localhost、IP 地址、端口或路径: ${raw:-空}"
        return 1
    fi
}

persist_public_domain_settings() {
    if [ "$DEPLOY_MODE" != "public" ]; then
        return 0
    fi
    if [ -z "$PUBLIC_MEMBER_DOMAIN" ] || [ -z "$PUBLIC_TRACE_DOMAIN" ]; then
        echo "[WARN] 未检测到完整公网域名配置，已跳过顾客前台/追溯域名系统设置写入。"
        return 0
    fi

    echo "[INFO] 正在写入顾客前台与商品追溯运行时域名配置..."
    local retry_count=0
    until docker exec zentea-db psql -U postgres -d zentea_db -tAc "SELECT to_regclass('public.system_settings')" 2>/dev/null | grep -q "system_settings" || [ $retry_count -eq 30 ]; do
        echo "[INFO] 正在等待 ERP 后端初始化 system_settings 表..."
        sleep 2
        retry_count=$((retry_count + 1))
    done

    if ! docker exec zentea-db psql -U postgres -d zentea_db -tAc "SELECT to_regclass('public.system_settings')" 2>/dev/null | grep -q "system_settings"; then
        echo "[WARN] system_settings 表暂未就绪，请稍后在后台系统设置中手动填写："
        echo "       顾客会员前台域名: $PUBLIC_MEMBER_DOMAIN"
        echo "       商品追溯页域名: $PUBLIC_TRACE_DOMAIN"
        return 0
    fi

    if docker exec -i zentea-db psql -U postgres -d zentea_db \
        -v member_domain="$PUBLIC_MEMBER_DOMAIN" \
        -v trace_domain="$PUBLIC_TRACE_DOMAIN" \
        -v ON_ERROR_STOP=1 <<'SQL'
INSERT INTO system_settings (key, value, description, is_secret, updated_at)
VALUES
  ('member_portal_domain', :'member_domain', '顾客会员前台独立域名，例如 https://member.example.com', false, NOW()),
  ('trace_portal_domain', :'trace_domain', '商品追溯页独立域名，例如 https://trace.example.com', false, NOW())
ON CONFLICT (key) DO UPDATE
SET value = EXCLUDED.value,
    description = EXCLUDED.description,
    is_secret = EXCLUDED.is_secret,
    updated_at = NOW();
SQL
    then
        echo "[OK] 顾客前台与商品追溯域名已写入系统设置。"
    else
        echo "[WARN] 域名系统设置写入失败，请稍后在后台系统设置中手动填写："
        echo "       顾客会员前台域名: $PUBLIC_MEMBER_DOMAIN"
        echo "       商品追溯页域名: $PUBLIC_TRACE_DOMAIN"
    fi
}

redact_backend_diagnostics() {
    python3 -c '
import re
import sys

text = sys.stdin.read()
text = re.sub(r"ZT-[A-Za-z0-9-]{8,128}", "ZT-[REDACTED]", text)
text = re.sub(
    r"(?i)\b(Bearer|Basic)\s+[A-Za-z0-9._~+/=-]+",
    r"\1 [REDACTED]",
    text,
)
text = re.sub(
    r"(?i)(license[_ -]?key|authorization|password|secret|token)(\s*[\":=]\s*)([^\s,;]+)",
    r"\1\2[REDACTED]",
    text,
)
sys.stdout.write(text)
'
}

print_backend_startup_diagnostics() {
    echo "[INFO] ERP 后端启动诊断（敏感内容已过滤）："
    (
        cd /opt/zentea
        docker compose ps backend 2>&1
    ) | redact_backend_diagnostics || true

    if ! docker inspect zentea-backend >/dev/null 2>&1; then
        echo "[ERROR] 未找到 zentea-backend 容器。"
        return 0
    fi

    docker inspect --format \
        '容器状态={{.State.Status}}，退出码={{.State.ExitCode}}，重启次数={{.RestartCount}}，健康状态={{if .State.Health}}{{.State.Health.Status}}{{else}}未配置{{end}}' \
        zentea-backend 2>&1 | redact_backend_diagnostics || true
    echo "[INFO] zentea-backend 最近 200 行日志："
    docker logs --tail 200 zentea-backend 2>&1 | redact_backend_diagnostics || true
}

activate_local_license() {
    echo "[INFO] 正在完成本机授权激活..."

    local retry_count=0
    until docker exec zentea-backend curl -fsS http://127.0.0.1:8000/api/v1/health >/dev/null 2>&1; do
        local container_state="missing"
        local restart_count="0"
        container_state=$(docker inspect --format '{{.State.Status}}' zentea-backend 2>/dev/null || echo "missing")
        restart_count=$(docker inspect --format '{{.RestartCount}}' zentea-backend 2>/dev/null || echo "0")
        if ! [[ "$restart_count" =~ ^[0-9]+$ ]]; then
            restart_count=0
        fi
        if [ "$container_state" = "exited" ] || [ "$container_state" = "dead" ] || \
           [ "$container_state" = "missing" ] || [ "$restart_count" -ge 3 ]; then
            echo "[ERROR] ERP 后端未能稳定启动，本机授权激活尚未发起。"
            print_backend_startup_diagnostics
            return 1
        fi
        if [ "$retry_count" -ge 60 ]; then
            echo "[ERROR] ERP 后端健康检查超时，无法完成本机授权激活。"
            print_backend_startup_diagnostics
            return 1
        fi
        sleep 2
        retry_count=$((retry_count + 1))
    done

    local activation_output=""
    if ! activation_output=$(printf '%s' "$LICENSE_KEY" | docker exec -i zentea-backend python -c '
import asyncio
import sys

from app.services.license import license_service


async def activate_and_verify():
    license_key = sys.stdin.read().strip()
    if not license_key:
        print("授权码为空")
        return False

    stored_key = await license_service.get_stored_license_key()
    if stored_key == license_key:
        status = await license_service.verify(force=True)
        if status.get("valid"):
            print("本机授权已激活且验证有效")
            return True

    result = await license_service.activate(license_key)
    if not result.get("success"):
        print(result.get("message") or "授权中心拒绝激活")
        return False

    status = await license_service.verify(force=True)
    if not status.get("valid"):
        print(status.get("message") or "激活后的授权验证未通过")
        return False

    print("本机授权激活并验证成功")
    return True


raise SystemExit(0 if asyncio.run(activate_and_verify()) else 1)
'); then
        echo "[ERROR] 本机授权激活失败: ${activation_output:-未返回详细原因}"
        return 1
    fi

    echo "[OK] ${activation_output:-本机授权激活并验证成功}"
}

# 检测是否具备可交互的终端 (TTY)
# 正式安装必须交互确认 HTTPS 域名。非交互环境不再回退到不安全且无法启动的
# HTTP 单机/局域网配置。
if [ ! -c /dev/tty ]; then
    echo "[ERROR] 正式安装需要交互输入 HTTPS 域名，当前终端不可交互。"
    echo "        请通过 SSH 登录客户服务器后重新执行标准安装命令。"
    exit 1
fi

echo "==========================================================================="
echo "               茗管家 ZenTea ERP HTTPS 域名配置引导"
echo "==========================================================================="
echo "正式商用部署必须使用公网域名和 HTTPS，不支持 HTTP 单机或局域网 IP 访问。"
echo ""
echo " 1) A方案: 单域名部署方案 (仅需一个域名，推荐)"
echo "    - 所有子系统共享一个域名（例如 erp.example.com）。"
echo ""
echo " 2) B方案: 三域名独立方案"
echo "    - 商家端后台、顾客端登录、商品防伪溯源分别使用独立的子域名。"
echo "==========================================================================="
read -p "请输入您的选项 (1 或 2, 直接回车默认选择 1): " SCHEME_CHOICE </dev/tty
if [ -z "$SCHEME_CHOICE" ]; then
    SCHEME_CHOICE="1"
fi
if [ "$SCHEME_CHOICE" != "1" ] && [ "$SCHEME_CHOICE" != "2" ]; then
    echo "[ERROR] 域名方案只能选择 1 或 2。"
    exit 1
fi
DOMAIN_SCHEME="$SCHEME_CHOICE"

if [ "$DOMAIN_SCHEME" = "1" ]; then
    read -p "请输入您绑定的公网域名 (例如 erp.example.com，可带 https://): " CUSTOM_DOMAIN </dev/tty
    if [ -z "$CUSTOM_DOMAIN" ]; then
        echo "[ERROR] 正式安装必须填写公网 HTTPS 域名，已安全停止。"
        exit 1
    fi
    require_public_domain "$CUSTOM_DOMAIN" || exit 1
    PUBLIC_ADMIN_DOMAIN="$(normalize_public_origin "$CUSTOM_DOMAIN")"
    PUBLIC_MEMBER_DOMAIN="$PUBLIC_ADMIN_DOMAIN"
    PUBLIC_TRACE_DOMAIN="$PUBLIC_ADMIN_DOMAIN"
    NGINX_ADMIN_DOMAIN="$(public_origin_host "$PUBLIC_ADMIN_DOMAIN")"
    NGINX_MEMBER_DOMAIN="$NGINX_ADMIN_DOMAIN"
    NGINX_TRACE_DOMAIN="$NGINX_ADMIN_DOMAIN"
    CORS_ORIGINS="[\"$PUBLIC_ADMIN_DOMAIN\"]"
    echo ">> [OK] 已将单域名 $PUBLIC_ADMIN_DOMAIN 写入本地配置！"
else
    echo ">> 您选择了三域名方案。请输入以下三个子域名："
    read -p "1. ERP 商家管理后台域名 (例如 erp.example.com): " DOMAIN_ADMIN </dev/tty
    read -p "2. 顾客端登录与寄存查询域名 (例如 member.example.com): " DOMAIN_MEMBER </dev/tty
    read -p "3. 商品防伪溯源专属短域名 (例如 trace.example.com): " DOMAIN_TRACE </dev/tty
    if [ -z "$DOMAIN_ADMIN" ] || [ -z "$DOMAIN_MEMBER" ] || [ -z "$DOMAIN_TRACE" ]; then
        echo "[ERROR] 三域名方案的域名不能为空，已安全停止。"
        exit 1
    fi
    require_public_domain "$DOMAIN_ADMIN" || exit 1
    require_public_domain "$DOMAIN_MEMBER" || exit 1
    require_public_domain "$DOMAIN_TRACE" || exit 1
    PUBLIC_ADMIN_DOMAIN="$(normalize_public_origin "$DOMAIN_ADMIN")"
    PUBLIC_MEMBER_DOMAIN="$(normalize_public_origin "$DOMAIN_MEMBER")"
    PUBLIC_TRACE_DOMAIN="$(normalize_public_origin "$DOMAIN_TRACE")"
    NGINX_ADMIN_DOMAIN="$(public_origin_host "$PUBLIC_ADMIN_DOMAIN")"
    NGINX_MEMBER_DOMAIN="$(public_origin_host "$PUBLIC_MEMBER_DOMAIN")"
    NGINX_TRACE_DOMAIN="$(public_origin_host "$PUBLIC_TRACE_DOMAIN")"
    CORS_ORIGINS="[\"$PUBLIC_ADMIN_DOMAIN\",\"$PUBLIC_MEMBER_DOMAIN\",\"$PUBLIC_TRACE_DOMAIN\"]"
    echo ">> [OK] 已将三域名配置成功写入本地配置！"
fi

# ==================== 茗管家数据灾备与密钥配置 ====================
IS_FIRST_INSTALL="1"
IS_RESUME_INSTALL="0"
BACKUP_KEY=""
SECRET_KEY_VAL=""
ADMIN_PASSWORD=""

read_env_value() {
    local key="$1"
    local file="$2"
    [ -f "$file" ] || return 0
    grep -m1 "^${key}=" "$file" 2>/dev/null | cut -d'=' -f2-
}

# 安装器可能在 ERP 已启动后，仅因 Nginx/证书阶段的 apt 锁失败而被再次执行。
# 这种续装必须保留已经写入数据库所使用的管理员密码及全部恢复密钥，绝不能
# 重新生成并覆盖凭据文件，否则会出现“文件中的密码与数据库密码不一致”，并
# 可能导致历史令牌、加密字段和备份不可恢复。
if [ -s /opt/zentea/.env ]; then
    chown root:root /opt/zentea/.env
    chmod 0600 /opt/zentea/.env
    IS_FIRST_INSTALL="0"
    IS_RESUME_INSTALL="1"
    SECRET_KEY_VAL=$(read_env_value SECRET_KEY /opt/zentea/.env)
    BACKUP_KEY=$(read_env_value BACKUP_ENCRYPTION_KEY /opt/zentea/.env)
    ADMIN_PASSWORD=$(read_env_value DEFAULT_ADMIN_PASSWORD /opt/zentea/.env)

    if [ -z "$SECRET_KEY_VAL" ] && [ -s /etc/zentea-upgrader/recovery.env ]; then
        SECRET_KEY_VAL=$(read_env_value SECRET_KEY /etc/zentea-upgrader/recovery.env)
    fi
    if [ -z "$BACKUP_KEY" ] && [ -s /etc/zentea-upgrader/recovery.env ]; then
        BACKUP_KEY=$(read_env_value BACKUP_ENCRYPTION_KEY /etc/zentea-upgrader/recovery.env)
    fi
    if [ -z "$SECRET_KEY_VAL" ] || [ -z "$BACKUP_KEY" ]; then
        echo "[ERROR] 检测到已有安装，但无法读取原 SECRET_KEY 或 BACKUP_ENCRYPTION_KEY。"
        echo "        为防止覆盖恢复密钥，安装器已安全停止；请检查 /opt/zentea/.env 与 recovery.env。"
        exit 1
    fi
    echo "[INFO] 检测到未完成或已有安装，将保留原管理员凭据、系统密钥和备份密钥继续安装。"
fi

if [ "$IS_RESUME_INSTALL" != "1" ] && [ -c /dev/tty ]; then
    echo "==========================================================================="
    echo "               茗管家 ZenTea ERP 数据灾备与恢复引导"
    echo "==========================================================================="
    echo "请选择本次安装的性质："
    echo ""
    echo " 1) 全新首次安装 (系统将自动为您生成高强度数据加密密钥)"
    echo ""
    echo " 2) 灾后重建/数据恢复安装 (允许您填入原有的数据加密密钥及系统密钥以还原数据)"
    echo "==========================================================================="
    read -p "请输入选项 (1 或 2, 直接回车默认选择 1): " INSTALL_TYPE_CHOICE </dev/tty
    
    if [ "$INSTALL_TYPE_CHOICE" = "2" ]; then
        IS_FIRST_INSTALL="0"
        
        # 允许输入原有备份加密密钥
        read -r -s -p "请输入您原有的备份加密密钥 (BACKUP_ENCRYPTION_KEY, 默认备份请直接回车留空): " BACKUP_KEY </dev/tty
        echo "" >/dev/tty
        
        # 必须输入原有的 SECRET_KEY
        while [ -z "$SECRET_KEY_VAL" ]; do
            read -r -s -p "请输入您原有的系统安全密钥 (SECRET_KEY, 必填): " SECRET_KEY_VAL </dev/tty
            echo "" >/dev/tty
            if [ -z "$SECRET_KEY_VAL" ]; then
                echo "[ERROR] 系统安全密钥不能为空，请重新输入！"
            fi
        done
    fi
fi

if [ -z "$SECRET_KEY_VAL" ]; then
    # 首次安装，自动生成 48 位强随机系统密钥
    SECRET_KEY_VAL=$(openssl rand -hex 32)
fi

if [ -z "$BACKUP_KEY" ]; then
    # 首次安装，自动生成 32 位强随机备份密钥
    BACKUP_KEY=$(openssl rand -hex 32)
fi

# 提取或分配已有的 REDIS_PASSWORD
REDIS_PASSWORD_VAL=""
if [ -f /opt/zentea/.env ]; then
    REDIS_PASSWORD_VAL=$(grep '^REDIS_PASSWORD=' /opt/zentea/.env | cut -d'=' -f2-)
fi
if [ -z "$REDIS_PASSWORD_VAL" ]; then
    REDIS_PASSWORD_VAL=$(openssl rand -hex 24)
fi

if [ "$IS_RESUME_INSTALL" != "1" ]; then
    ADMIN_PASSWORD=$(openssl rand -base64 24 | tr -d '\n')
fi

# 生成容器端 .env 文件
cat > /opt/zentea/.env << EOF
POSTGRES_USER=postgres
POSTGRES_PASSWORD=${DB_PASSWORD}
POSTGRES_DB=zentea_db
REDIS_PASSWORD=${REDIS_PASSWORD_VAL}
SECRET_KEY=${SECRET_KEY_VAL}
ENV=production
VERSION=${LATEST_VERSION}
ENABLE_ONLINE_UPGRADE=true
ZENTEA_GID=${ZENTEA_GID}
ZENTEA_BACKEND_IMAGE=$(image_ref "$BACKEND_IMAGE_PATH" "$BACKEND_IMAGE_DIGEST")
BACKEND_IMAGE=$(image_ref "$BACKEND_IMAGE_PATH" "$BACKEND_IMAGE_DIGEST")
BACKEND_CORS_ORIGINS=${CORS_ORIGINS}
BIND_HOST=${BIND_HOST}
DEFAULT_ADMIN_USERNAME=zenteaerp
DEFAULT_ADMIN_PASSWORD=${ADMIN_PASSWORD}
BACKUP_ENCRYPTION_KEY=${BACKUP_KEY}
EOF
chmod 0600 /opt/zentea/.env

cat > /etc/zentea-upgrader/recovery.env << EOF
BACKUP_ENCRYPTION_KEY=${BACKUP_KEY}
SECRET_KEY=${SECRET_KEY_VAL}
EOF
chmod 0600 /etc/zentea-upgrader/recovery.env

if [ -n "$ADMIN_PASSWORD" ]; then
cat > /root/zentea-initial-admin.txt << EOF
username=zenteaerp
password=${ADMIN_PASSWORD}
EOF
chmod 0600 /root/zentea-initial-admin.txt
fi

if [ -n "$FRONTEND_IMAGE_PATH" ]; then
    {
        echo "ZENTEA_FRONTEND_IMAGE=$(image_ref "$FRONTEND_IMAGE_PATH" "$FRONTEND_IMAGE_DIGEST")"
        echo "FRONTEND_IMAGE=$(image_ref "$FRONTEND_IMAGE_PATH" "$FRONTEND_IMAGE_DIGEST")"
    } >> /opt/zentea/.env
fi

# 从云端下载并校验 docker-compose 模板
download_verified "${DEPLOY_SERVER_URL}/static/templates/docker-compose.client.yml" /opt/zentea/docker-compose.yml "$COMPOSE_SHA256"
chmod 0644 /opt/zentea/docker-compose.yml

# 执行首次拉起
cd /opt/zentea

DOCKER_USER=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); print(data.get('docker_username', ''))" 2>/dev/null || true)
DOCKER_PASS=$(python3 -c "import json; data=json.load(open('$LICENSE_RESPONSE')); print(data.get('docker_password', ''))" 2>/dev/null || true)
REGISTRY_HOST=$(echo "$BACKEND_IMAGE_PATH" | cut -d/ -f1)

if [ -n "$DOCKER_USER" ] && [ -n "$DOCKER_PASS" ]; then
    echo "[INFO] 检测到私有仓库鉴权凭证，正在登录私有镜像服务: $REGISTRY_HOST ..."
    cat > /etc/zentea-upgrader/registry.env << EOF
REGISTRY_HOST=${REGISTRY_HOST}
REGISTRY_USERNAME=${DOCKER_USER}
REGISTRY_PASSWORD=${DOCKER_PASS}
EOF
    chmod 0600 /etc/zentea-upgrader/registry.env
    echo "$DOCKER_PASS" | docker login --username "$DOCKER_USER" --password-stdin "$REGISTRY_HOST"
fi

docker compose pull
docker compose up -d

if [ -n "$DOCKER_USER" ] && [ -n "$DOCKER_PASS" ]; then
    echo "[INFO] 镜像拉取成功，正在注销私有镜像登录状态..."
    docker logout "$REGISTRY_HOST" || true
fi

# ==========================================
# 8. 强行同步并重置物理数据库内部密码
# ==========================================
echo "[INFO] 正在校验并对齐物理数据库通信凭证..."
CURRENT_PASS=$(grep '^POSTGRES_PASSWORD=' /opt/zentea/.env | cut -d'=' -f2-)
if [ -n "$CURRENT_PASS" ]; then
    RETRY_COUNT=0
    until docker exec zentea-db pg_isready -U postgres &>/dev/null || [ $RETRY_COUNT -eq 15 ]; do
        echo "[INFO] 正在等待数据库容器服务就绪..."
        sleep 2
        RETRY_COUNT=$((RETRY_COUNT + 1))
    done
    
    if docker exec zentea-db pg_isready -U postgres &>/dev/null; then
        echo "[INFO] 正在强行同步物理数据库主密码..."
        if docker exec zentea-db psql -U postgres -d zentea_db -c "ALTER USER postgres WITH PASSWORD '${CURRENT_PASS}';" &>/dev/null; then
            echo "[OK] 物理数据库密码已完美同步对齐！"
            echo "[INFO] 正在重新拉起后端服务以完成最新配置装载..."
            docker compose restart backend
        else
            echo "[WARN] 物理数据库凭证对齐未完成（可能是空库或已成功配置），如无法访问请尝试重启。"
        fi
    else
        echo "[WARN] 数据库响应超时，已跳过密码强行对齐，这不影响首次安装。"
    fi
fi

persist_public_domain_settings

if ! activate_local_license; then
    echo "[ERROR] 安装未完成，请根据上述具体错误处理后重新运行安装器。"
    exit 1
fi

echo "==========================================================================="
echo "               ⚡️ 自动启动: 域名反代与 HTTPS SSL 安全证书配置"
echo "==========================================================================="
echo "[INFO] 正在从分发站下载域名装配程序..."

if download_verified "${DEPLOY_SERVER_URL}/setup-nginx.sh" "$NGINX_SETUP" "$NGINX_SETUP_SHA256" 2>/dev/null; then
    chmod +x "$NGINX_SETUP"
    if bash "$NGINX_SETUP" \
        --domain-scheme "$DOMAIN_SCHEME" \
        --admin-domain "$NGINX_ADMIN_DOMAIN" \
        --member-domain "$NGINX_MEMBER_DOMAIN" \
        --trace-domain "$NGINX_TRACE_DOMAIN" \
        --ssl-email "admin@$NGINX_ADMIN_DOMAIN"; then
        true
    else
        echo "[WARN] Nginx 域名证书自动配置未全部完成（可能由于您的域名解析尚未在全球生效）。"
        echo "       待域名解析生效后，请重新运行已校验安装器完成域名配置。"
        true
    fi
else
    echo "[WARN] 无法从分发站下载域名配置脚本，请确保网络畅通。"
    echo "       请检查网络后重新运行已校验安装器，禁止直接管道执行远程脚本。"
fi

echo "==========================================================================="
echo "       🎉 恭喜！茗管家 ZenTea ERP 进销存系统已顺利部署并配置完成！"
echo "==========================================================================="
echo "系统当前版本: $LATEST_VERSION"
if [ "$DOMAIN_SCHEME" = "1" ]; then
    echo "  - 系统访问域名: ${PUBLIC_ADMIN_DOMAIN}"
else
    echo "  - 1. ERP 商家后台管理域名:  ${PUBLIC_ADMIN_DOMAIN}"
    echo "  - 2. 顾客个人端与寄存域名:  ${PUBLIC_MEMBER_DOMAIN}"
    echo "  - 3. 商品安全防伪溯源域名:  ${PUBLIC_TRACE_DOMAIN}"
    echo "  - 提示: 打印商品防伪标签时，二维码网址已启用专属短域名 ${PUBLIC_TRACE_DOMAIN}！"
fi
echo ""
echo "  - 默认管理员账号: zenteaerp"
    echo "  - 初始账号凭据已保存到仅 root 可读的 /root/zentea-initial-admin.txt"
echo "==========================================================================="

if [ "$IS_RESUME_INSTALL" = "1" ]; then
    echo ""
    echo "  [OK] 已按续装模式保留原管理员凭据、SECRET_KEY 和 BACKUP_ENCRYPTION_KEY。"
    echo "       本次执行未轮换数据库用户、系统加密或备份恢复凭据。"
elif [ "$IS_FIRST_INSTALL" = "1" ]; then
    echo ""
    echo "  【重要】请将恢复密钥文件安全转移到离线密码库或加密介质。"
    echo "  茗管家已启用强加密数据备份（支持本地打包及阿里云 OSS 自动备份）。"
    echo "  一旦服务器物理损坏需要重装系统，您必须在新安装中填入以下密钥对才能还原数据。"
    echo "  恢复密钥文件: /etc/zentea-upgrader/recovery.env（权限 0600）"
    echo "  【警告】如果丢失上述密钥，历史生成的 H5 / OSS 加密备份文件将永远无法解密！"
    echo "  ------------------------------------------------------------------------"
else
    echo ""
    echo "  [OK] 数据恢复密钥对已成功注入容器（BACKUP_ENCRYPTION_KEY / SECRET_KEY）。"
    echo "       请登录后台的 [数据归档/系统维护] 菜单，从本地上传或直接从阿里云 OSS 恢复您的数据！"
fi
unset LICENSE_KEY DOCKER_PASS SECRET_KEY_VAL BACKUP_KEY DB_PASSWORD REDIS_PASSWORD_VAL ADMIN_PASSWORD
echo "==========================================================================="
