#!/bin/bash

# 数字档案管理系统前端 - 多阶段构建脚本
# 支持开发环境构建和生成Docker镜像

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="digital-archive-frontend"
IMAGE_NAME="${PROJECT_NAME}"
IMAGE_TAG="latest"
BUILD_TYPE="${1:-prod}"  # 构建类型：dev, prod, stage
DOCKER_REGISTRY=""        # Docker镜像仓库地址
PUSH_IMAGE="${2:-false}"  # 是否推送镜像

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

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

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

log_step() {
    echo -e "${BLUE}[STEP]${NC} $1"
}

# 显示帮助信息
show_help() {
    echo "用法: $0 [构建类型] [是否推送镜像]"
    echo ""
    echo "构建类型:"
    echo "  dev     开发环境构建"
    echo "  prod    生产环境构建（默认）"
    echo "  stage   测试环境构建"
    echo ""
    echo "是否推送镜像:"
    echo "  true    构建完成后推送镜像到仓库"
    echo "  false   仅构建镜像，不推送（默认）"
    echo ""
    echo "环境变量:"
    echo "  DOCKER_REGISTRY  设置Docker镜像仓库地址"
    echo ""
    echo "示例:"
    echo "  $0                    # 生产环境构建，不推送镜像"
    echo "  $0 dev                # 开发环境构建"
    echo "  $0 prod true          # 生产环境构建并推送镜像"
    echo "  DOCKER_REGISTRY=registry.example.com $0 prod true  # 推送到指定仓库"
}

# 检查依赖
check_dependencies() {
    log_step "检查构建依赖..."
    
    # 检查Node.js
    if ! command -v node &> /dev/null; then
        log_error "Node.js 未安装"
        exit 1
    fi
    
    # 检查npm
    if ! command -v npm &> /dev/null; then
        log_error "npm 未安装"
        exit 1
    fi
    
    # 检查Docker
    if ! command -v docker &> /dev/null; then
        log_error "Docker 未安装"
        exit 1
    fi
    
    log_info "Node.js版本: $(node --version)"
    log_info "npm版本: $(npm --version)"
    log_info "Docker版本: $(docker --version)"
}

# 清理构建缓存
clean_build_cache() {
    log_step "清理构建缓存..."
    
    # 清理npm缓存
    npm cache clean --force
    
    # 清理Docker构建缓存
    docker builder prune -f
    
    # 删除悬空镜像
    docker image prune -f
    
    log_info "构建缓存清理完成"
}

# 安装依赖
install_dependencies() {
    log_step "安装项目依赖..."
    
    # 设置npm镜像源
    npm config set registry https://registry.npmmirror.com
    
    # 安装依赖
    if [[ "$BUILD_TYPE" == "dev" ]]; then
        npm ci --production=false
    else
        npm ci
    fi
    
    log_info "依赖安装完成"
}

# 执行代码检查
run_code_checks() {
    log_step "执行代码质量检查..."
    
    # ESLint检查
    log_info "运行ESLint检查..."
    if ! npm run lint; then
        log_warn "ESLint检查发现一些问题，请检查代码质量"
    fi
    
    log_info "代码检查完成"
}

# 构建前端应用
build_frontend() {
    log_step "构建前端应用..."
    
    case "$BUILD_TYPE" in
        "dev")
            log_info "开发环境构建..."
            npm run build:stage
            ;;
        "prod")
            log_info "生产环境构建..."
            npm run build:prod
            ;;
        "stage")
            log_info "测试环境构建..."
            npm run build:stage
            ;;
        *)
            log_error "未知的构建类型: $BUILD_TYPE"
            show_help
            exit 1
            ;;
    esac
    
    # 检查构建结果
    if [ ! -d "dist" ]; then
        log_error "构建失败，dist目录未生成"
        exit 1
    fi
    
    log_info "前端应用构建完成"
}

# 构建Docker镜像
build_docker_image() {
    log_step "构建Docker镜像..."
    
    local full_image_name="${IMAGE_NAME}:${IMAGE_TAG}"
    
    # 如果有镜像仓库地址，添加前缀
    if [ -n "$DOCKER_REGISTRY" ]; then
        full_image_name="${DOCKER_REGISTRY}/${full_image_name}"
    fi
    
    log_info "构建镜像: $full_image_name"
    
    # 构建Docker镜像
    docker build \
        --tag "$full_image_name" \
        --build-arg BUILD_TYPE="$BUILD_TYPE" \
        --no-cache \
        .
    
    # 验证镜像构建
    if ! docker image inspect "$full_image_name" > /dev/null 2>&1; then
        log_error "Docker镜像构建失败"
        exit 1
    fi
    
    log_info "Docker镜像构建完成: $full_image_name"
    
    # 显示镜像信息
    docker images | grep "$IMAGE_NAME"
}

# 推送Docker镜像
push_docker_image() {
    if [[ "$PUSH_IMAGE" != "true" ]]; then
        return
    fi
    
    log_step "推送Docker镜像..."
    
    local full_image_name="${IMAGE_NAME}:${IMAGE_TAG}"
    
    # 如果有镜像仓库地址，添加前缀
    if [ -n "$DOCKER_REGISTRY" ]; then
        full_image_name="${DOCKER_REGISTRY}/${full_image_name}"
    else
        log_error "未设置DOCKER_REGISTRY环境变量，无法推送镜像"
        return
    fi
    
    # 登录Docker仓库（如果需要）
    if [[ "$DOCKER_REGISTRY" != "" ]]; then
        log_info "登录Docker仓库: $DOCKER_REGISTRY"
        # 这里可以根据需要添加登录逻辑
        # docker login $DOCKER_REGISTRY
    fi
    
    # 推送镜像
    log_info "推送镜像: $full_image_name"
    docker push "$full_image_name"
    
    log_info "镜像推送完成"
}

# 生成部署信息文件
generate_deploy_info() {
    log_step "生成部署信息..."
    
    local deploy_info="deploy-info.json"
    
    cat > "$deploy_info" << EOF
{
    "project": "$PROJECT_NAME",
    "build_type": "$BUILD_TYPE",
    "image_name": "$IMAGE_NAME",
    "image_tag": "$IMAGE_TAG",
    "docker_registry": "$DOCKER_REGISTRY",
    "build_time": "$(date -Iseconds)",
    "git_commit": "$(git rev-parse HEAD 2>/dev/null || echo 'unknown')",
    "git_branch": "$(git branch --show-current 2>/dev/null || echo 'unknown')",
    "node_version": "$(node --version)",
    "npm_version": "$(npm --version)"
}
EOF
    
    log_info "部署信息已生成: $deploy_info"
}

# 显示构建摘要
show_summary() {
    log_step "构建摘要"
    echo ""
    echo "项目名称: $PROJECT_NAME"
    echo "构建类型: $BUILD_TYPE"
    echo "镜像名称: $IMAGE_NAME:$IMAGE_TAG"
    
    if [ -n "$DOCKER_REGISTRY" ]; then
        echo "镜像仓库: $DOCKER_REGISTRY"
    fi
    
    echo "构建时间: $(date)"
    echo ""
    
    if [[ "$PUSH_IMAGE" == "true" && -n "$DOCKER_REGISTRY" ]]; then
        echo "镜像已推送到: $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG"
    else
        echo "镜像已构建完成，可使用以下命令运行:"
        echo "  docker run -d -p 80:80 $IMAGE_NAME:$IMAGE_TAG"
    fi
    
    echo ""
}

# 主构建流程
main() {
    # 检查帮助参数
    if [[ "$1" == "-h" || "$1" == "--help" ]]; then
        show_help
        exit 0
    fi
    
    log_info "开始构建数字档案管理系统前端..."
    log_info "构建类型: $BUILD_TYPE"
    
    check_dependencies
    clean_build_cache
    install_dependencies
    run_code_checks
    build_frontend
    build_docker_image
    push_docker_image
    generate_deploy_info
    show_summary
    
    log_info "构建完成！"
}

# 执行主函数
main "$@"