#!/bin/bash

################################################################################
# FFWS DEV 开发环境部署脚本 (dev.sh)
################################################################################
#
# DEV (Development) 开发环境管理工具
#
# 端口范围: 30XX
#   - 前端:     3000
#   - 后端:     3001
#   - PostgreSQL: 3002
#   - Redis:    3003
#   - Temporal: 3033/3034
#   - MinIO:    3090/3091
#
# 使用方法：
#   bash scripts/dev.sh [命令] [选项]
#
################################################################################

set -e

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

# 获取脚本所在目录和项目根目录
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
PROJECT_ROOT=$(cd "$SCRIPT_DIR/../.." && pwd)  # 修复: 需要往上两级才是项目根目录
DOCKER_DIR="$PROJECT_ROOT/docker"
LOGS_DIR="$PROJECT_ROOT/logs/dev"

# DEV 环境配置
ENV_FILE="$DOCKER_DIR/.env"
COMPOSE_FILE="$DOCKER_DIR/docker-compose.yml"
CONTAINER_PREFIX="ffws-dev"
PROJECT_NAME="ffws-dev"

# DEV 端口配置（默认值，会被 .env 中的值覆盖）
DEV_FRONTEND_PORT=${FRONTEND_PORT:-3000}
DEV_BACKEND_PORT=${BACKEND_PORT:-3001}
DEV_POSTGRES_PORT=${POSTGRES_PORT:-5432}
DEV_REDIS_PORT=${REDIS_PORT:-6379}

# 创建日志目录
mkdir -p "$LOGS_DIR"
mkdir -p "$PROJECT_ROOT/backend/logs"
mkdir -p "$PROJECT_ROOT/frontend/logs"

# 日志函数
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"
}

log_success() {
    echo -e "${GREEN}✅${NC} $1"
}

# 检测操作系统
detect_os() {
    if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        echo "linux"
    elif [[ "$OSTYPE" == "darwin"* ]]; then
        echo "macos"
    elif [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]] || [[ "$OSTYPE" == "win32" ]]; then
        echo "windows"
    else
        echo "unknown"
    fi
}

OS_TYPE=$(detect_os)

# Windows 环境提示
if [ "$OS_TYPE" == "windows" ]; then
    # 检查是否在 Git Bash 中
    if [[ "$TERM_PROGRAM" != "" ]] || [[ "$MSYSTEM" != "" ]]; then
        : # 在 Git Bash 或 MSYS2 中，继续执行
    fi
fi

# 确保日志目录存在
mkdir -p "$PROJECT_ROOT/logs"

# 检查并杀死占用端口的进程
kill_port() {
    local port=$1
    local desc=$2
    local pid=""
    
    if [ "$OS_TYPE" == "macos" ]; then
        pid=$(lsof -ti:$port 2>/dev/null || true)
    elif [ "$OS_TYPE" == "windows" ]; then
        # Windows: netstat 输出格式为 "协议 本地地址 外部地址 状态 PID"
        # 只匹配 LISTENING 状态，避免匹配到外部端口
        pid=$(netstat -ano 2>/dev/null | grep "LISTENING" | grep -E "[:.]$port[[:space:]]" | awk '{print $5}' | head -1 || true)
    else
        if command -v ss &> /dev/null; then
            pid=$(ss -tlnp 2>/dev/null | grep ":$port " | sed -E 's/.*pid=([0-9]+).*/\1/' | head -1 || true)
        else
            pid=$(fuser $port/tcp 2>/dev/null || true)
        fi
    fi
    
    if [ -n "$pid" ] && [ "$pid" != "0" ]; then
        log_warn "端口 $port 被占用 ($desc, PID: $pid)，正在释放..."
        if [ "$OS_TYPE" == "windows" ]; then
            # 在 Windows 上先检查进程是否存在
            if tasklist //FI "PID eq $pid" 2>/dev/null | grep -q "$pid"; then
                taskkill //F //PID $pid 2>/dev/null || true
                sleep 2
            fi
        else
            if ps -p $pid > /dev/null 2>&1; then
                kill -9 $pid 2>/dev/null || true
                sleep 1
            fi
        fi
    fi
}

# 显示帮助信息
show_help() {
    echo -e "${CYAN}╔═══════════════════════════════════════════════════════════╗${NC}"
    echo -e "${CYAN}║                                                           ║${NC}"
    echo -e "${CYAN}║         FFWS DEV 开发环境部署工具 (dev.sh)               ║${NC}"
    echo -e "${CYAN}║                                                           ║${NC}"
    echo -e "${CYAN}╚═══════════════════════════════════════════════════════════╝${NC}"
    echo ""
    echo -e "${YELLOW}用法:${NC}"
    echo "    bash scripts/dev.sh [命令] [选项]"
    echo ""
    echo -e "${YELLOW}基础服务管理:${NC}"
    echo -e "    ${GREEN}up${NC}                 启动 Docker 服务 (PostgreSQL + Redis)"
    echo "        --all           所有服务 (包含 Temporal, MinIO)"
    echo "        --temporal      包含 Temporal"
    echo "        --storage       包含 MinIO"
    echo ""
    echo -e "    ${GREEN}down${NC}               停止 Docker 服务"
    echo "        --volumes       同时删除数据卷 ⚠️"
    echo ""
    echo -e "    ${GREEN}restart${NC}            重启 Docker 服务"
    echo -e "    ${GREEN}status${NC}             查看服务状态"
    echo -e "    ${GREEN}logs${NC} [service]     查看 Docker 日志"
    echo ""
    echo -e "${YELLOW}数据库管理:${NC}"
    echo -e "    ${GREEN}db:migrate${NC}         运行数据库迁移"
    echo -e "    ${GREEN}db:push${NC}            推送数据库结构 (无迁移记录)"
    echo -e "    ${GREEN}db:seed${NC}            运行种子数据"
    echo -e "    ${GREEN}db:studio${NC}          打开 Prisma Studio"
    echo -e "    ${GREEN}db:backup${NC}          备份数据库"
    echo -e "    ${GREEN}db:restore${NC} <file>  恢复数据库"
    echo -e "    ${GREEN}db:reset${NC}           重置数据库 ⚠️"
    echo ""
    echo -e "${YELLOW}初始化命令:${NC}"
    echo -e "    ${GREEN}init:permissions${NC}   初始化权限和角色"
    echo -e "    ${GREEN}init:admin${NC}         创建管理员用户 (itadmin)"
    echo -e "    ${GREEN}init:all${NC}           完整初始化 (权限 + 管理员)"
    echo ""
    echo -e "${YELLOW}开发命令:${NC}"
    echo -e "    ${GREEN}run${NC}                启动开发服务器 ⭐"
    echo "        --backend       仅后端"
    echo "        --frontend      仅前端"
    echo ""
    echo -e "    ${GREEN}start${NC}              启动应用 (前端 + 后端)"
    echo "        --backend       仅启动后端"
    echo "        --frontend      仅启动前端"
    echo ""
    echo -e "    ${GREEN}stop${NC}               停止应用"
    echo "        --backend       仅停止后端"
    echo "        --frontend      仅停止前端"
    echo ""
    echo -e "    ${GREEN}app:logs${NC} [app]     查看应用日志"
    echo "        backend         后端日志"
    echo "        frontend        前端日志"
    echo ""
    echo -e "${YELLOW}维护命令:${NC}"
    echo -e "    ${GREEN}health${NC}             健康检查"
    echo -e "    ${GREEN}clean${NC}              清理资源"
    echo "        --all           清理所有 (包含 node_modules) ⚠️"
    echo "        --cache         仅清理构建缓存"
    echo -e "    ${GREEN}env:check${NC}          检查环境变量配置"
    echo -e "    ${GREEN}env:create${NC}         创建环境变量模板"
    echo ""
    echo -e "${YELLOW}Agent Pool（开发 agent 池，并行任务推荐入口）:${NC}"
    echo -e "    ${GREEN}pool:init${NC}          初始化 agent 池（默认 3 slot）"
    echo -e "    ${GREEN}pool:resize${NC} --size N  调整池大小"
    echo -e "    ${GREEN}pool:destroy${NC}       销毁池（释放所有资源）"
    echo -e "    ${GREEN}pool:status${NC}        查看池状态（同 agent:status）"
    echo -e "    ${GREEN}pool:sweep${NC}         GC stale lock"
    echo -e "    ${GREEN}agent:claim${NC} <branch> 占一个 slot（stdout 是 export 行，需 eval）"
    echo -e "    ${GREEN}agent:release${NC} [N]  释放 slot"
    echo "        详见 scripts/dev/agent-pool/README.md"
    echo ""
    echo -e "${YELLOW}示例:${NC}"
    echo "    # 启动基础服务"
    echo "    bash scripts/dev.sh up"
    echo ""
    echo "    # 启动所有服务"
    echo "    bash scripts/dev.sh up --all"
    echo ""
    echo "    # 启动开发服务器"
    echo "    bash scripts/dev.sh run"
    echo ""
    echo "    # 仅启动后端开发服务器"
    echo "    bash scripts/dev.sh run --backend"
    echo ""
    echo "    # 停止应用"
    echo "    bash scripts/dev.sh stop"
    echo ""
    echo "    # 查看日志"
    echo "    bash scripts/dev.sh logs postgres"
    echo ""
    echo -e "${YELLOW}端口映射 (30XX):${NC}"
    echo "    - 前端:        http://localhost:3000"
    echo "    - 后端 API:    http://localhost:3001/api/v1"
    echo "    - PostgreSQL:  localhost:3002"
    echo "    - Redis:       localhost:3003"
    echo "    - Temporal UI: http://localhost:3080 (需要 --temporal)"
    echo "    - MinIO:       http://localhost:3091 (需要 --storage)"
    echo ""
}

# 检查并设置环境变量文件
# 使用统一的 .env 文件（根目录）
check_env_file() {
    # 优先使用根目录的 .env 文件
    local root_env="$PROJECT_ROOT/.env"
    
    if [ -f "$root_env" ]; then
        # 确保 docker/.env 是软链接
        if [ ! -e "$ENV_FILE" ] || [ ! -L "$ENV_FILE" ]; then
            log_info "创建 docker/.env 软链接指向根目录 .env..."
            cd "$DOCKER_DIR"
            ln -sf ../.env .env 2>/dev/null || true
            cd "$PROJECT_ROOT"
        fi
        ENV_FILE="$DOCKER_DIR/.env"
        log_success "使用统一环境变量文件: $root_env (通过软链接)"
    elif [ -f "$ENV_FILE" ] || [ -L "$ENV_FILE" ]; then
        # docker/.env 存在（可能是软链接）
        log_info "使用环境变量文件: $ENV_FILE"
    else
        log_error "环境变量文件不存在: $root_env"
        log_info "请先创建环境变量文件:"
        log_info "  bash scripts/env/setup-env.sh development"
        log_info "或者使用:"
        log_info "  bash scripts/dev/dev.sh env:create"
        exit 1
    fi
}

# 加载环境变量 (确保文件存在后再加载)
load_env() {
    check_env_file
    source "$ENV_FILE"
    # 用 .env 中的端口覆盖默认值
    DEV_FRONTEND_PORT=${FRONTEND_PORT:-$DEV_FRONTEND_PORT}
    DEV_BACKEND_PORT=${BACKEND_PORT:-$DEV_BACKEND_PORT}
    DEV_POSTGRES_PORT=${POSTGRES_PORT:-$DEV_POSTGRES_PORT}
    DEV_REDIS_PORT=${REDIS_PORT:-$DEV_REDIS_PORT}
}

# 创建环境变量模板
create_env_template() {
    if [ -f "$ENV_FILE" ]; then
        log_warn "环境变量文件已存在: $ENV_FILE"
        read -p "$(echo -e ${YELLOW}是否覆盖？[y/N]: ${NC})" confirm
        if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
            log_info "已取消"
            return
        fi
    fi
    
    cat > "$ENV_FILE" << 'EOF'
# FFWS DEV 开发环境配置
# 端口范围: 30XX

# ============================================
# PostgreSQL 配置 (必需)
# ============================================
POSTGRES_DB=ffws_dev
POSTGRES_USER=ffws_dev
POSTGRES_PASSWORD=CHANGE_ME_POSTGRES_PASSWORD

# ============================================
# Redis 配置 (必需)
# ============================================
REDIS_PASSWORD=CHANGE_ME_REDIS_PASSWORD

# ============================================
# MinIO 配置 (使用 storage profile 时必需)
# ============================================
MINIO_ROOT_USER=ffws_minio
MINIO_ROOT_PASSWORD=CHANGE_ME_MINIO_PASSWORD

# ============================================
# 应用配置
# ============================================
NODE_ENV=development
API_URL=http://localhost:3001
FRONTEND_URL=http://localhost:3000

# ============================================
# JWT 配置
# ============================================
JWT_SECRET=CHANGE_ME_JWT_SECRET_AT_LEAST_32_CHARS

# ============================================
# 其他配置
# ============================================
# LOG_LEVEL=debug
EOF
    
    log_success "环境变量模板已创建: $ENV_FILE"
    log_warn "请编辑文件并修改所有 CHANGE_ME_* 的值！"
}

# 检查环境变量配置
check_env_config() {
    log_step "检查环境变量配置..."
    
    # 使用 load_env 确保文件存在并加载
    load_env
    
    local has_error=false
    
    # 检查必需变量
    local required_vars=(
        "POSTGRES_DB"
        "POSTGRES_USER"
        "POSTGRES_PASSWORD"
        "REDIS_PASSWORD"
    )
    
    for var in "${required_vars[@]}"; do
        if [ -z "${!var}" ]; then
            log_error "缺少必需变量: $var"
            has_error=true
        elif [[ "${!var}" == *"CHANGE_ME"* ]]; then
            log_warn "变量未修改: $var (仍包含 CHANGE_ME)"
            has_error=true
        fi
    done
    
    if [ "$has_error" = true ]; then
        log_error "环境变量配置检查失败"
        return 1
    fi
    
    log_success "环境变量配置检查通过"
    return 0
}

# 检查 Docker 是否运行
check_docker() {
    # 首先检查 docker 命令是否存在
    if ! command -v docker &> /dev/null; then
        log_error "Docker 未安装"
        log_info "请先安装 Docker: https://docs.docker.com/engine/install/"
        exit 1
    fi
    
    # 检查 Docker daemon 是否运行
    if ! docker info > /dev/null 2>&1; then
        # 可能是权限问题，尝试检查 Docker 服务状态
        if [ "$OS_TYPE" == "linux" ]; then
            # 检查 Docker 服务是否运行
            if systemctl is-active --quiet docker 2>/dev/null; then
                log_error "Docker 正在运行，但当前用户无权限访问"
                log_info "解决方案 (选择一种):"
                log_info "  1. 将用户添加到 docker 组: sudo usermod -aG docker \$USER"
                log_info "     然后重新登录或运行: newgrp docker"
                log_info "  2. 使用 sudo 运行此脚本: sudo bash scripts/dev.sh ..."
            else
                log_error "Docker 服务未运行"
                log_info "启动 Docker: sudo systemctl start docker"
                log_info "设置开机启动: sudo systemctl enable docker"
            fi
        elif [ "$OS_TYPE" == "macos" ]; then
            log_error "Docker 未运行"
            log_info "请先启动 Docker Desktop"
        else
            log_error "Docker 未运行或无权限访问"
        fi
        exit 1
    fi
}

# 启动服务
cmd_up() {
    local profile="basic"
    
    # 解析参数
    while [[ $# -gt 0 ]]; do
        case $1 in
            --all) profile="all"; shift ;;
            --basic) profile="basic"; shift ;;
            --temporal) profile="temporal"; shift ;;
            --storage) profile="storage"; shift ;;
            *) shift ;;
        esac
    done
    
    check_docker
    check_env_file
    
    echo ""
    log_info "🚀 启动 FFWS DEV 环境 (配置: $profile)..."
    echo ""
    
    cd "$DOCKER_DIR"
    
    case $profile in
        all)
            docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" \
                --profile core --profile temporal --profile storage up -d
            ;;
        basic)
            docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" \
                --profile core up -d
            ;;
        temporal)
            docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" \
                --profile core --profile temporal up -d
            ;;
        storage)
            docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" \
                --profile core --profile storage up -d
            ;;
    esac
    
    echo ""
    log_success "Docker 服务已启动"
    
    # 等待服务就绪
    log_info "等待服务就绪..."
    sleep 5
    
    # 显示服务状态
    cmd_status
    
    echo ""
    log_info "服务地址:"
    echo -e "  PostgreSQL: ${CYAN}localhost:$DEV_POSTGRES_PORT${NC}"
    echo -e "  Redis:      ${CYAN}localhost:$DEV_REDIS_PORT${NC}"
    
    if [ "$profile" = "all" ] || [ "$profile" = "temporal" ]; then
        echo -e "  Temporal:   ${CYAN}http://localhost:3080${NC}"
    fi
    
    if [ "$profile" = "all" ] || [ "$profile" = "storage" ]; then
        echo -e "  MinIO:      ${CYAN}http://localhost:3091${NC}"
    fi
    echo ""
}

# 停止服务
cmd_down() {
    local clean_volumes=false
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --volumes|-v) clean_volumes=true; shift ;;
            *) shift ;;
        esac
    done
    
    check_docker
    
    cd "$DOCKER_DIR"
    
    if [ "$clean_volumes" = true ]; then
        log_warn "停止服务并清除数据卷..."
        docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" down -v
        log_success "服务已停止，数据卷已清除"
    else
        log_step "停止服务..."
        docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" down
        log_success "服务已停止，数据已保留"
    fi
}

# 重启服务
cmd_restart() {
    log_step "重启 DEV 服务..."
    cmd_down
    sleep 2
    cmd_up "$@"
}

# 查看状态
cmd_status() {
    check_docker
    
    echo ""
    log_info "📊 DEV 服务状态"
    echo ""
    
    cd "$DOCKER_DIR"
    docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" ps 2>/dev/null || log_info "无运行中的服务"
    echo ""
}

# 查看日志
cmd_logs() {
    local service=$1
    local follow=false
    
    shift || true
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            -f|--follow) follow=true; shift ;;
            *) shift ;;
        esac
    done
    
    check_docker
    
    cd "$DOCKER_DIR"
    
    if [ -z "$service" ]; then
        if [ "$follow" = true ]; then
            docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs -f
        else
            docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs --tail=100
        fi
    else
        if [ "$follow" = true ]; then
            docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs -f "$service"
        else
            docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs --tail=100 "$service"
        fi
    fi
}

# 数据库迁移
cmd_db_migrate() {
    log_step "运行数据库迁移..."
    
    # 确保容器在运行
    check_docker
    
    # 从环境变量构建 DATABASE_URL
    load_env
    
    export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${DEV_POSTGRES_PORT}/${POSTGRES_DB}?schema=public"
    
    cd "$PROJECT_ROOT/backend"
    npm run prisma:migrate
    
    log_success "数据库迁移完成"
}

# 推送数据库结构
cmd_db_push() {
    log_step "推送数据库结构..."
    
    load_env
    
    export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${DEV_POSTGRES_PORT}/${POSTGRES_DB}?schema=public"
    
    cd "$PROJECT_ROOT/backend"
    npm run db:push:force
    
    log_success "数据库结构已推送"
}

# 运行种子数据
cmd_db_seed() {
    log_step "运行种子数据..."

    load_env

    export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${DEV_POSTGRES_PORT}/${POSTGRES_DB}?schema=public"

    cd "$PROJECT_ROOT/backend"
    npm run db:seed

    log_success "种子数据已导入"
}

# 打开 Prisma Studio
cmd_db_studio() {
    log_step "打开 Prisma Studio..."
    
    load_env
    
    export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${DEV_POSTGRES_PORT}/${POSTGRES_DB}?schema=public"
    
    cd "$PROJECT_ROOT/backend"
    npm run prisma:studio
}

# 重置数据库
cmd_db_reset() {
    log_warn "⚠️  重置数据库将删除所有数据！"
    read -p "$(echo -e ${RED}确认重置？[y/N]: ${NC})" confirm
    
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
        log_info "已取消"
        return
    fi
    
    log_step "重置数据库..."
    
    load_env
    
    export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${DEV_POSTGRES_PORT}/${POSTGRES_DB}?schema=public"
    
    cd "$PROJECT_ROOT/backend"
    npm run db:reset
    
    log_success "数据库已重置"
}

# 初始化权限和角色
cmd_init_permissions() {
    echo ""
    log_info "🔐 初始化权限和角色..."
    echo ""
    
    load_env
    
    export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${DEV_POSTGRES_PORT}/${POSTGRES_DB}?schema=public"
    
    cd "$PROJECT_ROOT/backend"
    
    # 使用推荐的种子脚本
    log_step "运行权限种子脚本..."
    npm run init:permissions
    
    echo ""
    log_success "权限和角色初始化完成"
    echo ""
}

# 初始化管理员用户
cmd_init_admin() {
    echo ""
    log_info "👤 初始化管理员用户..."
    echo ""
    
    load_env
    
    export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${DEV_POSTGRES_PORT}/${POSTGRES_DB}?schema=public"
    
    cd "$PROJECT_ROOT/backend"
    
    log_step "创建 IT Admin 用户..."
    npm run init:itadmin
    
    echo ""
    log_success "管理员用户初始化完成"
    echo ""
    echo -e "${CYAN}登录信息:${NC}"
    echo -e "  用户名:  ${GREEN}itadmin${NC}"
    echo -e "  邮箱:    ${GREEN}itadmin@ff.com${NC}"
    echo -e "  密码:    ${YELLOW}请查看脚本输出或联系管理员${NC}"
    echo ""
}

# 完整初始化 (权限 + 管理员)
cmd_init_all() {
    echo ""
    echo -e "${CYAN}════════════════════════════════════════════════════════════════${NC}"
    echo -e "${CYAN}🚀 DEV 系统完整初始化${NC}"
    echo -e "${CYAN}════════════════════════════════════════════════════════════════${NC}"
    echo ""
    
    # 1. 初始化权限
    log_step "[1/2] 初始化权限和角色..."
    cmd_init_permissions
    
    # 2. 初始化管理员
    log_step "[2/2] 初始化管理员用户..."
    cmd_init_admin
    
    echo ""
    echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
    echo -e "${GREEN}✅ 系统初始化完成！${NC}"
    echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
    echo ""
}

# 备份数据库
cmd_db_backup() {
    log_step "备份数据库..."
    
    load_env
    
    local backup_dir="$PROJECT_ROOT/backups/dev"
    mkdir -p "$backup_dir"
    
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local backup_file="$backup_dir/dev_backup_$timestamp.sql.gz"
    
    docker exec ${CONTAINER_PREFIX}-postgres pg_dump \
        -U "$POSTGRES_USER" "$POSTGRES_DB" | gzip > "$backup_file"
    
    log_success "数据库已备份: $backup_file"
    
    # 显示文件大小（兼容 Windows）
    if command -v du &> /dev/null; then
        log_info "大小: $(du -h "$backup_file" | cut -f1)"
    elif [ -f "$backup_file" ]; then
        # Windows 下使用 ls -lh 作为替代
        local size=$(ls -lh "$backup_file" 2>/dev/null | awk '{print $5}')
        [ -n "$size" ] && log_info "大小: $size"
    fi
}

# 恢复数据库
cmd_db_restore() {
    local backup_file=$1
    
    if [ -z "$backup_file" ]; then
        log_error "请指定备份文件"
        log_info "用法: bash scripts/dev.sh db:restore <backup_file>"
        exit 1
    fi
    
    if [ ! -f "$backup_file" ]; then
        log_error "备份文件不存在: $backup_file"
        exit 1
    fi
    
    log_warn "⚠️  恢复数据库将覆盖现有数据！"
    read -p "$(echo -e ${RED}确认恢复？[y/N]: ${NC})" confirm
    
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
        log_info "已取消"
        return
    fi
    
    load_env
    
    log_step "恢复数据库..."
    
    gunzip -c "$backup_file" | docker exec -i ${CONTAINER_PREFIX}-postgres \
        psql -U "$POSTGRES_USER" -d "$POSTGRES_DB"
    
    log_success "数据库已恢复"
}

# 启动开发服务器 (run = 开发模式启动)
cmd_run() {
    local backend_only=false
    local frontend_only=false
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --backend) backend_only=true; shift ;;
            --frontend) frontend_only=true; shift ;;
            *) shift ;;
        esac
    done
    
    local target_desc="应用"
    if [ "$backend_only" = true ]; then
        target_desc="后端"
    elif [ "$frontend_only" = true ]; then
        target_desc="前端"
    fi
    
    echo ""
    echo -e "${CYAN}════════════════════════════════════════════════════════════════${NC}"
    echo -e "${CYAN}🚀 DEV ${target_desc}开发服务器${NC}"
    echo -e "${CYAN}════════════════════════════════════════════════════════════════${NC}"
    echo ""
    
    # Windows 特别提示
    if [ "$OS_TYPE" == "windows" ] && [ "$backend_only" = false ] && [ "$frontend_only" = false ]; then
        log_warn "Windows 提示: 后台模式在关闭终端后可能不稳定"
        log_info "建议: 使用 --backend 或 --frontend 分别在不同终端启动"
        echo ""
    fi
    
    # 1. 检查 Docker 服务
    log_step "[1/3] 检查 Docker 服务..."
    if ! docker ps | grep -q "${CONTAINER_PREFIX}-postgres"; then
        log_warn "Docker 服务未运行，正在启动..."
        cmd_up
        sleep 3
    fi
    log_success "Docker 服务正常"
    echo ""
    
    # 2. 检查依赖
    log_step "[2/3] 检查依赖..."
    if [ "$frontend_only" = false ]; then
        if [ ! -d "$PROJECT_ROOT/backend/node_modules" ]; then
            log_info "安装后端依赖..."
            cd "$PROJECT_ROOT/backend" && npm install
        fi
        # 生成 Prisma Client
        cd "$PROJECT_ROOT/backend" && npm run prisma:generate 2>/dev/null || true
    fi
    
    if [ "$backend_only" = false ]; then
        if [ ! -d "$PROJECT_ROOT/frontend/node_modules" ]; then
            log_info "安装前端依赖..."
            cd "$PROJECT_ROOT/frontend" && npm install
        fi
    fi
    log_success "依赖检查完成"
    echo ""
    
    # 3. 启动开发服务器
    log_step "[3/3] 启动${target_desc}开发服务器..."
    
    if [ "$backend_only" = true ]; then
        kill_port $DEV_BACKEND_PORT "后端"
        cd "$PROJECT_ROOT/backend"
        log_info "启动后端开发服务器..."
        npm run start:dev
    elif [ "$frontend_only" = true ]; then
        kill_port $DEV_FRONTEND_PORT "前端"
        cd "$PROJECT_ROOT/frontend"
        log_info "启动前端开发服务器..."
        npm run dev
    else
        # 同时启动前后端（后台模式）
        kill_port $DEV_BACKEND_PORT "后端"
        kill_port $DEV_FRONTEND_PORT "前端"
        
        # 启动后端
        log_info "启动后端开发服务器 (后台)..."
        cd "$PROJECT_ROOT/backend"
        nohup npm run start:dev > "$LOGS_DIR/backend.log" 2>&1 &
        echo $! > "$LOGS_DIR/backend.pid"
        
        # 等待后端启动
        sleep 3
        
        # 启动前端
        log_info "启动前端开发服务器 (后台)..."
        cd "$PROJECT_ROOT/frontend"
        nohup npm run dev > "$LOGS_DIR/frontend.log" 2>&1 &
        echo $! > "$LOGS_DIR/frontend.pid"
        
        # 等待启动
        sleep 5
        
        echo ""
        echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
        echo -e "${GREEN}✅ DEV 开发服务器已启动！${NC}"
        echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
        echo ""
        echo -e "${CYAN}服务地址:${NC}"
        echo -e "  前端:      ${CYAN}http://localhost:$DEV_FRONTEND_PORT${NC}"
        echo -e "  后端 API:  ${CYAN}http://localhost:$DEV_BACKEND_PORT/api/v1${NC}"
        echo ""
        echo -e "${CYAN}查看日志:${NC}"
        echo -e "  后端:  ${GREEN}tail -f $LOGS_DIR/backend.log${NC}"
        echo -e "  前端:  ${GREEN}tail -f $LOGS_DIR/frontend.log${NC}"
        echo ""
        echo -e "${CYAN}停止服务:${NC}"
        echo -e "  ${GREEN}bash scripts/dev.sh stop${NC}"
        echo ""
    fi
}

# 启动应用 (后台模式)
cmd_start() {
    local backend_only=false
    local frontend_only=false
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --backend) backend_only=true; shift ;;
            --frontend) frontend_only=true; shift ;;
            *) shift ;;
        esac
    done
    
    echo ""
    log_info "🚀 启动 DEV 应用"
    echo ""
    
    # 检查 Docker 服务
    log_step "检查 Docker 服务..."
    if ! docker ps | grep -q "${CONTAINER_PREFIX}-postgres"; then
        log_warn "Docker 服务未运行，正在启动..."
        cmd_up
        sleep 3
    fi
    log_success "Docker 服务正常"
    
    # 启动应用
    if [ "$backend_only" = true ]; then
        kill_port $DEV_BACKEND_PORT "后端"
        log_step "启动后端..."
        cd "$PROJECT_ROOT/backend"
        nohup npm run start:dev > "$LOGS_DIR/backend.log" 2>&1 &
        echo $! > "$LOGS_DIR/backend.pid"
        log_success "后端已启动"
    elif [ "$frontend_only" = true ]; then
        kill_port $DEV_FRONTEND_PORT "前端"
        log_step "启动前端..."
        cd "$PROJECT_ROOT/frontend"
        nohup npm run dev > "$LOGS_DIR/frontend.log" 2>&1 &
        echo $! > "$LOGS_DIR/frontend.pid"
        log_success "前端已启动"
    else
        kill_port $DEV_BACKEND_PORT "后端"
        kill_port $DEV_FRONTEND_PORT "前端"
        
        log_step "启动后端..."
        cd "$PROJECT_ROOT/backend"
        nohup npm run start:dev > "$LOGS_DIR/backend.log" 2>&1 &
        echo $! > "$LOGS_DIR/backend.pid"
        
        log_step "启动前端..."
        cd "$PROJECT_ROOT/frontend"
        nohup npm run dev > "$LOGS_DIR/frontend.log" 2>&1 &
        echo $! > "$LOGS_DIR/frontend.pid"
        
        log_success "应用已启动"
    fi
    
    # 等待服务启动
    sleep 3
    
    echo ""
    echo -e "${CYAN}服务地址:${NC}"
    if [ "$backend_only" = false ]; then
        echo -e "  前端:      ${CYAN}http://localhost:$DEV_FRONTEND_PORT${NC}"
    fi
    if [ "$frontend_only" = false ]; then
        echo -e "  后端 API:  ${CYAN}http://localhost:$DEV_BACKEND_PORT/api/v1${NC}"
    fi
    echo ""
    echo -e "${CYAN}查看日志:${NC}"
    if [ "$frontend_only" = false ]; then
        echo -e "  后端:  ${GREEN}tail -f $LOGS_DIR/backend.log${NC}"
    fi
    if [ "$backend_only" = false ]; then
        echo -e "  前端:  ${GREEN}tail -f $LOGS_DIR/frontend.log${NC}"
    fi
    echo ""
}

# 停止应用
cmd_stop() {
    local backend_only=false
    local frontend_only=false
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --backend) backend_only=true; shift ;;
            --frontend) frontend_only=true; shift ;;
            *) shift ;;
        esac
    done
    
    echo ""
    log_info "🛑 停止 DEV 应用"
    echo ""
    
    # 停止后端
    if [ "$frontend_only" = false ]; then
        log_step "停止后端服务..."
        
        # 通过 PID 文件停止
        if [ -f "$LOGS_DIR/backend.pid" ]; then
            local pid=$(cat "$LOGS_DIR/backend.pid")
            if [ -n "$pid" ] && [ "$pid" != "0" ]; then
                if [ "$OS_TYPE" == "windows" ]; then
                    # 检查进程是否存在
                    if tasklist //FI "PID eq $pid" 2>/dev/null | grep -q "$pid"; then
                        taskkill //F //PID $pid 2>/dev/null || true
                        sleep 1
                    fi
                else
                    if ps -p $pid > /dev/null 2>&1; then
                        kill -9 $pid 2>/dev/null || true
                        sleep 1
                    fi
                fi
            fi
            rm -f "$LOGS_DIR/backend.pid"
        fi
        
        # 确保端口释放
        kill_port $DEV_BACKEND_PORT "后端"
        log_success "后端已停止"
    fi
    
    # 停止前端
    if [ "$backend_only" = false ]; then
        log_step "停止前端服务..."
        
        # 通过 PID 文件停止
        if [ -f "$LOGS_DIR/frontend.pid" ]; then
            local pid=$(cat "$LOGS_DIR/frontend.pid")
            if [ -n "$pid" ] && [ "$pid" != "0" ]; then
                if [ "$OS_TYPE" == "windows" ]; then
                    # 检查进程是否存在
                    if tasklist //FI "PID eq $pid" 2>/dev/null | grep -q "$pid"; then
                        taskkill //F //PID $pid 2>/dev/null || true
                        sleep 1
                    fi
                else
                    if ps -p $pid > /dev/null 2>&1; then
                        kill -9 $pid 2>/dev/null || true
                        sleep 1
                    fi
                fi
            fi
            rm -f "$LOGS_DIR/frontend.pid"
        fi
        
        # 确保端口释放
        kill_port $DEV_FRONTEND_PORT "前端"
        log_success "前端已停止"
    fi
    
    echo ""
    log_success "应用已停止"
    echo ""
}

# 查看应用日志
cmd_app_logs() {
    local app=$1
    
    case $app in
        backend|back|b)
            tail -f "$LOGS_DIR/backend.log"
            ;;
        frontend|front|f)
            tail -f "$LOGS_DIR/frontend.log"
            ;;
        *)
            # 显示所有应用日志
            tail -f "$LOGS_DIR/backend.log" "$LOGS_DIR/frontend.log" 2>/dev/null || \
                log_error "日志文件不存在，请先启动应用"
            ;;
    esac
}

# 健康检查
cmd_health() {
    echo ""
    log_info "🏥 DEV 健康检查"
    echo ""
    
    # 尝试加载环境变量 (健康检查可以在没有配置文件的情况下运行)
    check_env_file 2>/dev/null || true
    if [ -f "$ENV_FILE" ]; then
        source "$ENV_FILE"
    fi
    
    # 检查 PostgreSQL
    log_step "检查 PostgreSQL..."
    if docker exec ${CONTAINER_PREFIX}-postgres pg_isready -U "${POSTGRES_USER:-ffws_dev}" > /dev/null 2>&1; then
        log_success "PostgreSQL 健康"
    else
        log_error "PostgreSQL 不健康"
    fi
    
    # 检查 Redis
    log_step "检查 Redis..."
    if docker exec ${CONTAINER_PREFIX}-redis redis-cli -a "${REDIS_PASSWORD:-}" ping > /dev/null 2>&1; then
        log_success "Redis 健康"
    else
        log_error "Redis 不健康"
    fi
    
    # 检查后端 (如果正在运行)
    log_step "检查后端 API..."
    if curl -sf "http://localhost:$DEV_BACKEND_PORT/api/v1/health" > /dev/null 2>&1; then
        log_success "后端 API 健康"
    else
        log_warn "后端 API 未运行或不健康"
    fi
    
    # 检查前端 (如果正在运行)
    log_step "检查前端..."
    if curl -sf "http://localhost:$DEV_FRONTEND_PORT" > /dev/null 2>&1; then
        log_success "前端健康"
    else
        log_warn "前端未运行"
    fi
    
    echo ""
}

# 清理资源
cmd_clean() {
    local clean_all=false
    local clean_cache=false
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --all) clean_all=true; shift ;;
            --cache) clean_cache=true; shift ;;
            *) shift ;;
        esac
    done
    
    echo ""
    
    if [ "$clean_cache" = true ]; then
        log_step "清理构建缓存..."
        
        # 清除前端缓存
        [ -d "$PROJECT_ROOT/frontend/.next" ] && rm -rf "$PROJECT_ROOT/frontend/.next" && log_info "已清除 .next"
        [ -d "$PROJECT_ROOT/frontend/node_modules/.cache" ] && rm -rf "$PROJECT_ROOT/frontend/node_modules/.cache"
        
        # 清除后端缓存
        [ -d "$PROJECT_ROOT/backend/dist" ] && rm -rf "$PROJECT_ROOT/backend/dist" && log_info "已清除 dist"
        [ -d "$PROJECT_ROOT/backend/node_modules/.cache" ] && rm -rf "$PROJECT_ROOT/backend/node_modules/.cache"
        
        log_success "缓存已清除"
        return
    fi
    
    if [ "$clean_all" = true ]; then
        log_warn "⚠️  此操作将删除所有 DEV 容器、数据卷和 node_modules"
        read -p "$(echo -e ${RED}确认删除？[y/N]: ${NC})" confirm
        
        if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
            log_info "已取消"
            return
        fi
        
        # 停止应用
        cmd_stop 2>/dev/null || true
        
        # 停止 Docker 并删除卷
        cmd_down --volumes
        
        # 删除 node_modules
        log_step "删除 node_modules..."
        [ -d "$PROJECT_ROOT/backend/node_modules" ] && rm -rf "$PROJECT_ROOT/backend/node_modules"
        [ -d "$PROJECT_ROOT/frontend/node_modules" ] && rm -rf "$PROJECT_ROOT/frontend/node_modules"
        
        # 清理缓存
        [ -d "$PROJECT_ROOT/frontend/.next" ] && rm -rf "$PROJECT_ROOT/frontend/.next"
        [ -d "$PROJECT_ROOT/backend/dist" ] && rm -rf "$PROJECT_ROOT/backend/dist"
        
        # 清理日志
        rm -rf "$LOGS_DIR"/*
        
        log_success "清理完成"
    else
        # 默认只停止服务
        cmd_down
    fi
    
    log_success "清理完成"
}

# 主函数
main() {
    if [ $# -eq 0 ]; then
        show_help
        exit 0
    fi
    
    local cmd=$1
    shift
    
    case $cmd in
        up)
            cmd_up "$@"
            ;;
        down)
            cmd_down "$@"
            ;;
        restart)
            cmd_restart "$@"
            ;;
        status)
            cmd_status
            ;;
        logs)
            cmd_logs "$@"
            ;;
        db:migrate)
            cmd_db_migrate
            ;;
        db:push)
            cmd_db_push
            ;;
        db:seed)
            cmd_db_seed
            ;;
        db:studio)
            cmd_db_studio
            ;;
        db:reset)
            cmd_db_reset
            ;;
        init:permissions)
            cmd_init_permissions
            ;;
        init:admin)
            cmd_init_admin
            ;;
        init:all)
            cmd_init_all
            ;;
        db:backup)
            cmd_db_backup
            ;;
        db:restore)
            cmd_db_restore "$@"
            ;;
        run)
            cmd_run "$@"
            ;;
        start)
            cmd_start "$@"
            ;;
        stop)
            cmd_stop "$@"
            ;;
        app:logs)
            cmd_app_logs "$@"
            ;;
        health)
            cmd_health
            ;;
        clean)
            cmd_clean "$@"
            ;;
        env:check)
            check_env_config
            ;;
        env:create)
            create_env_template
            ;;
        # Agent pool 快捷入口（薄壳，转交 scripts/dev/agent-pool/ 下的脚本）
        pool:init)
            bash "$(dirname "$0")/agent-pool/pool-init.sh" "$@"
            ;;
        pool:resize)
            bash "$(dirname "$0")/agent-pool/pool-resize.sh" "$@"
            ;;
        pool:destroy)
            bash "$(dirname "$0")/agent-pool/pool-destroy.sh" "$@"
            ;;
        pool:status|agent:status)
            bash "$(dirname "$0")/agent-pool/agent-status.sh" "$@"
            ;;
        pool:sweep|agent:sweep)
            bash "$(dirname "$0")/agent-pool/agent-sweep.sh" "$@"
            ;;
        agent:claim)
            # 注意：这条命令的 stdout 是 export 行，调用方应 eval
            bash "$(dirname "$0")/agent-pool/agent-claim.sh" "$@"
            ;;
        agent:release)
            bash "$(dirname "$0")/agent-pool/agent-release.sh" "$@"
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            log_error "未知命令: $cmd"
            echo ""
            log_info "运行 'bash scripts/dev.sh help' 查看帮助"
            exit 1
            ;;
    esac
}

# 运行主函数
main "$@"
