# -*- coding: utf-8 -*-
"""CLI command implementation."""

from entrypoints.cli.runtime import *

class ServerManagerCLI:
    """Server Manager CLI."""
    
    def __init__(self, server_root: str = None, config_path: str = None, quiet: bool = False):
        """初始化
        
        Args:
            server_root: 服务器根目录（命令行指定）
            config_path: 配置文件路径
        """
        # 先自动检测找到项目配置所在目录
        detected_root = self._detect_server_root()
        
        # 尝试从 user.config 读取配置的 server_root
        configured_root = self._read_configured_server_root(detected_root)
        
        # 优先级：命令行参数 > user.config 配置 > 自动检测
        if server_root:
            self.server_root = str(Path(server_root).resolve())
        elif configured_root:
            self.server_root = str(Path(configured_root).resolve())
        else:
            self.server_root = detected_root
        
        # 从 user.config 读取 run_dir，如果没有则使用默认值
        configured_run_dir = self._read_configured_run_dir(self.server_root)
        if configured_run_dir:
            run_path = Path(configured_run_dir)
            if not run_path.is_absolute():
                run_path = Path(self.server_root) / run_path
            self.run_dir = str(run_path.resolve())
        else:
            self.run_dir = str(Path(self.server_root) / 'run')
        
        self.config_path = get_server_manager_config_dir(self.server_root)
        self.cookie = 'ddxq2-node'
        self.quiet = quiet
        
        # 输出服务器根目录信息
        logger.info(f"服务器根目录: {self.server_root}")
        logger.info(f"运行目录: {self.run_dir}")
        if not self.quiet:
            print(f"[INFO] 服务器根目录: {self.server_root}")
            print(f"[INFO] 运行目录: {self.run_dir}")
        
        # 加载配置（从实际的服务器根目录）
        self._load_config(config_path)
        self._apply_terminal_launch_config()
        
        # 执行一次性版本迁移（幂等，已完成的迁移会自动跳过）
        try:
            # logger_func 传入的消息自带换行，所以使用 end='' 避免 print 再追加
            logger_func = (lambda msg: None) if self.quiet else (lambda msg: print(msg, end=''))
            run_startup_migrations(self.server_root, logger_func=logger_func)
        except Exception as e:
            logger.error(f"执行启动迁移失败: {e}", exc_info=True)
    
    def _read_tool_config_value(self, detected_root: str, key: str) -> str:
        """从 user.config 读取指定配置项，兼容旧项目的历史用户配置文件。
        
        Args:
            detected_root: 自动检测的根目录（用于定位项目配置）
            key: 配置项名称
        
        Returns:
            配置值，如果没有配置返回 None
        """
        candidates = (
            get_server_manager_config_dir(detected_root) / USER_CONFIG_FILE,
            get_server_manager_config_dir(detected_root) / LEGACY_USER_CONFIG_FILE,
            Path(detected_root) / 'config' / USER_CONFIG_FILE,
            Path(detected_root) / 'config' / LEGACY_USER_CONFIG_FILE,
            Path(detected_root) / 'config' / PROJECT_CONFIG_FILE,
            get_server_manager_config_dir(detected_root) / DEFAULT_CONFIG_FILE,
            get_server_manager_config_dir(detected_root) / LEGACY_DEFAULT_CONFIG_FILE,
            Path(detected_root) / 'config' / DEFAULT_CONFIG_FILE,
            Path(detected_root) / 'config' / LEGACY_DEFAULT_CONFIG_FILE,
        )
        for config_path in candidates:
            if not config_path.exists():
                continue
            try:
                with open(config_path, 'r', encoding='utf-8') as f:
                    for line in f:
                        line = line.strip()
                        if line.startswith(f'{key}='):
                            value = line.split('=', 1)[1].strip()
                            if value:
                                return value
            except Exception:
                pass
        
        return None
    
    def _read_configured_server_root(self, detected_root: str) -> str:
        """从 user.config 读取配置的服务器根目录"""
        return self._read_tool_config_value(detected_root, 'server_root')
    
    def _read_configured_run_dir(self, detected_root: str) -> str:
        """从 user.config 读取配置的运行目录"""
        return self._read_tool_config_value(detected_root, 'run_dir')
    
    def _detect_server_root(self) -> str:
        """自动检测服务器根目录（优先使用运行目录）"""
        # 候选目录：优先运行目录，再考虑脚本/exe 所在位置
        if getattr(sys, 'frozen', False):
            start_path = Path(sys.executable).parent
        else:
            start_path = Path(__file__).resolve().parent
        
        candidates = [
            Path.cwd(),  # 运行目录（当前工作目录）优先
            start_path,
            start_path.parent.parent,
        ]
        
        for path in candidates:
            if (path / 'apps').exists() and (path / 'config').exists():
                return str(path.resolve())
        
        # 从起始路径向上查找
        current = start_path
        for _ in range(5):
            if (current / 'apps').exists() and (current / 'config').exists():
                return str(current.resolve())
            current = current.parent
        
        return str(Path.cwd().resolve())
    
    def _load_config(self, config_path: str = None):
        """加载配置文件
        
        优先级（从低到高）：default.config < project.config < user.config < 指定的 config_path
        """
        # 优先使用指定的配置文件
        if config_path and Path(config_path).exists():
            self.config = read_config_file(str(config_path))
        else:
            # 使用最终确定的服务器根目录加载项目配置，避免从源码目录误探测并生成配置。
            server_root = Path(self.server_root).resolve()
            cfg, err = ensure_and_get_server_manager_config_dir(server_root)
            
            if cfg is None:
                if not self.quiet:
                    print(f"警告: 找不到有效的服务器根目录（缺少 config/ 或 .server_manager/config/{DEFAULT_CONFIG_FILE}）")
                    print(f"  服务器根目录: {server_root}")
                    if err:
                        print(f"  原因: {err}")
                self.config = {}
                return
            
            # 合并配置：default.config < project.config < user.config
            self.config = read_merged_config(str(server_root), run_dir=self.run_dir)
        
        # 从配置中读取常用设置
        self.prefix = self.config.get('prefix', 'ddxq2')
        self.db_host = self.config.get('db_host', '127.0.0.1')
        self.db_port = int(self.config.get('db_port', '3306'))
        self.db_user = self.config.get('db_user', 'root')
        self.db_pass = self.config.get('db_pass', '')
        self.cookie = self.config.get('cookie', 'ddxq2-node')

    def _apply_terminal_launch_config(self):
        """让 CLI 后台启动也使用 user.config 中的窗口设置。"""
        mode = (self.config.get('terminal_launch_mode') or '').strip().lower()
        terminal_exe = (
            self.config.get('terminal_exe_path')
            or self.config.get('terminal_custom_command')
            or ''
        ).strip()
        if (
            terminal_exe
            and self.config.get('terminal_custom_cwd')
            and not any(sep in terminal_exe for sep in ('/', '\\'))
        ):
            legacy_path = Path(self.config.get('terminal_custom_cwd')) / terminal_exe
            if legacy_path.is_file():
                terminal_exe = str(legacy_path.resolve())

        if mode:
            os.environ['SERVER_MANAGER_TERMINAL'] = mode
        if terminal_exe:
            os.environ['SERVER_MANAGER_TERMINAL_EXE'] = terminal_exe
        elif 'terminal_exe_path' in self.config or 'terminal_custom_command' in self.config:
            os.environ.pop('SERVER_MANAGER_TERMINAL_EXE', None)
        os.environ.pop('SERVER_MANAGER_TERMINAL_COMMAND', None)
        os.environ.pop('SERVER_MANAGER_TERMINAL_CWD', None)
    
    def list_servers(self) -> dict:
        """列出所有服务器"""
        servers = get_server_list(self.run_dir)
        
        print("\n========== 服务器列表 ==========")
        total = 0
        for server_type, server_list in servers.items():
            if server_list:
                type_name = get_server_type_name(server_type)
                print(f"\n【{type_name}】({len(server_list)} 个)")
                for server in sorted(server_list):
                    print(f"  - {server}")
                    total += 1
        
        if total == 0:
            print("  (暂无服务器)")
        
        print(f"\n总计: {total} 个服务器")
        print("================================\n")
        
        return servers
    
    def create_server_cmd(
        self,
        server_type: str,
        server_id: int,
        prefix: str = None,
        db_host: str = None,
        db_user: str = None,
        db_pass: str = None,
        db_port: int = None,
        login_node: str = None,
        center_node: str = None,
        server_name: str = None,
        tcp_port: int = None,
        http_port: int = None,
        open_time: str = None,
        overwrite: bool = False
    ) -> bool:
        """创建服务器
        
        Args:
            server_type: 服务器类型 (game/login/center/cross/client)
            server_id: 服务器ID
            prefix: 服务器前缀
            其他参数: 数据库和服务器配置
        
        Returns:
            是否成功
        """
        prefix = prefix or self.prefix
        db_host = db_host or self.db_host
        db_user = db_user or self.db_user
        db_pass = db_pass or self.db_pass
        db_port = db_port or self.db_port
        
        # 默认端口
        if not tcp_port or not http_port:
            default_tcp, default_http = get_default_port(server_type, server_id)
            tcp_port = tcp_port or default_tcp
            http_port = http_port or default_http
        
        # 默认服务器名称
        if not server_name and server_type == 'game':
            server_name = f'{prefix}_{server_id}'
        
        # 生成目录名
        server_dir = generate_server_dir_name(prefix, server_type, server_id)
        type_name = get_server_type_name(server_type)
        
        logger.info(f"创建服务器: type={server_type}, id={server_id}, dir={server_dir}")
        logger.debug(f"数据库配置: host={db_host}, port={db_port}, user={db_user}")
        
        print(f"\n========== 创建{type_name} ==========")
        print(f"服务器目录: {server_dir}")
        print(f"服务器ID: {server_id}")
        print(f"数据库: {db_host}:{db_port}")
        if tcp_port:
            print(f"TCP端口: {tcp_port}")
        if http_port:
            print(f"HTTP端口: {http_port}")
        if login_node:
            print(f"登录节点: {login_node}")
        if center_node:
            print(f"中心节点: {center_node}")
        
        # 创建服务器
        success, message, merged_config = create_server(
            server_root=self.server_root,
            run_dir=self.run_dir,
            server_type=server_type,
            server_id=server_id,
            prefix=prefix,
            db_host=db_host,
            db_user=db_user,
            db_pass=db_pass,
            db_port=db_port,
            login_node=login_node,
            center_node=center_node,
            server_name=server_name,
            tcp_port=tcp_port,
            http_port=http_port,
            open_time=open_time,
            overwrite=overwrite
        )
        
        if success:
            logger.info(f"服务器创建成功: {server_dir}")
            print(f"\n✓ {message}")
            print(f"配置文件: {self.run_dir}/{server_dir}/config/kv.config")
        else:
            logger.error(f"服务器创建失败: {server_dir}, 错误: {message}")
            print(f"\n✗ {message}")
        
        print("================================\n")
        
        return success
    
    def start_server(self, server_name: str, use_rebar: bool = True, 
                     foreground: bool = False) -> bool:
        """启动服务器
        
        Args:
            server_name: 服务器目录名（如 ddxq_game_s1）
            use_rebar: 是否使用 rebar3 启动
            foreground: 是否在前台运行
        
        Returns:
            是否成功启动
        """
        logger.info(f"启动服务器: {server_name}, rebar={use_rebar}, foreground={foreground}")
        
        # 检查服务器是否存在
        server_dir = Path(self.run_dir) / server_name
        if not server_dir.exists():
            logger.warning(f"服务器不存在: {server_name}")
            print(f"✗ 服务器 {server_name} 不存在")
            return False
        
        # 生成启动配置
        merged_config = generate_start_config(self.server_root, server_name)
        if not merged_config:
            print(f"✗ 无法生成 {server_name} 的启动配置")
            return False
        
        # 构建启动命令
        cmd = build_start_command_by_config(
            self.server_root, 
            merged_config, 
            self.cookie, 
            use_rebar
        )
        
        # 工作目录：统一使用服务器根目录
        # 因为 rebar3/erl 需要在根目录找到 rebar.config 和 _build
        # 日志通过 sys.config 配置为 run/<服务器名称>/log，不再修改 Erlang 工作目录
        working_dir = self.server_root
        
        print(f"\n========== 启动服务器 ==========")
        print(f"服务器: {server_name}")
        print(f"模式: {'rebar3 shell' if use_rebar else '快速启动'}")
        print(f"前台运行: {'是' if foreground else '否'}")
        print(f"工作目录: {working_dir}")
        
        if foreground:
            process = run_cmd_foreground(cmd, working_dir, server_name)
            try:
                process.wait()
            except KeyboardInterrupt:
                print("\n收到中断信号，停止服务器...")
                process.terminate()
        else:
            result = run_cmd_in_new_window(cmd, working_dir, server_name)
            print(f"启动方式: {result}")
        
        print("================================\n")
        return True
    
    def stop_server(self, server_name: str) -> bool:
        """停止服务器
        
        Args:
            server_name: 服务器名称或完整节点名
        
        Returns:
            是否成功
        """
        logger.info(f"停止服务器: {server_name}")
        
        game_host = get_local_ip()
        
        # 构建停止命令（参数列表，避免 shell 引号问题）
        args = build_stop_command(server_name, self.cookie, local_host=game_host)
        display_cmd = subprocess_args_to_display(args)
        logger.debug(f"停止命令: {display_cmd}")
        
        print(f"\n========== 停止服务器 ==========")
        print(f"服务器: {server_name}")
        print(f"命令: {display_cmd}")
        
        try:
            result = subprocess.run(args, timeout=15)
            if result.returncode == 0:
                logger.info(f"服务器停止成功: {server_name}")
                print(f"✓ 服务器 {server_name} 已停止")
                success = True
            else:
                logger.warning(f"停止服务器返回码非0: {server_name}, code={result.returncode}")
                print(f"✗ 停止服务器失败 (返回码: {result.returncode})")
                success = False
        except subprocess.TimeoutExpired:
            logger.warning(f"停止服务器超时: {server_name}")
            print(f"✗ 停止服务器超时")
            success = False
        except Exception as e:
            logger.error(f"停止服务器出错: {server_name}, 错误: {e}")
            print(f"✗ 停止服务器出错: {e}")
            success = False
        
        print("================================\n")
        return success
    
    def connect_server(self, server_name: str, target_ip: str = None) -> bool:
        """连接到服务器
        
        Args:
            server_name: 服务器名称或完整节点名
            target_ip: 目标IP（可选）
        
        Returns:
            是否成功
        """
        game_host = get_local_ip()
        # 构建连接命令
        cmd = build_remsh_command(server_name, self.cookie, target_ip, local_host=game_host)
        
        print(f"\n========== 连接服务器 ==========")
        print(f"目标: {server_name}")
        
        # 连接需要交互，直接在前台执行
        process = run_cmd_foreground(cmd, self.server_root, f"remsh-{server_name}")
        try:
            process.wait()
        except KeyboardInterrupt:
            print("\n断开连接")
            process.terminate()
        
        print("================================\n")
        return True
    
    def regenerate_config(self, server_name: str) -> bool:
        """重新生成服务器的 sys.config
        
        Args:
            server_name: 服务器目录名（如 ddxq_game_s1）
        
        Returns:
            是否成功
        """
        logger.info(f"重新生成配置: {server_name}")
        
        # 检查服务器是否存在
        server_dir = Path(self.run_dir) / server_name
        if not server_dir.exists():
            logger.warning(f"服务器不存在: {server_name}")
            print(f"✗ 服务器 {server_name} 不存在")
            return False
        
        # 检查是否有 kv.config
        kv_config_path = server_dir / 'config' / 'kv.config'
        if not kv_config_path.exists():
            logger.warning(f"kv.config 不存在: {server_name}")
            print(f"✗ 服务器 {server_name} 没有 kv.config 文件")
            return False
        
        print(f"\n========== 重新生成 sys.config ==========")
        print(f"服务器: {server_name}")
        
        # 生成配置
        merged_config = generate_start_config(self.server_root, server_name)
        if merged_config:
            config_file = merged_config.get('_config_file', '')
            logger.info(f"配置生成成功: {config_file}")
            print(f"✓ sys.config 已重新生成")
            print(f"配置文件: {config_file}")
            success = True
        else:
            logger.error(f"配置生成失败: {server_name}")
            print(f"✗ 生成 sys.config 失败，请检查 kv.config 和模板文件")
            success = False
        
        print("================================\n")
        return success
    
    def compile(self, target: str = 'all', server_type: str = 'game') -> bool:
        """编译代码
        
        Args:
            target: 编译目标 (all/code/proto/table/tbllog)
            server_type: 服务器类型 (game/login)
        
        Returns:
            是否成功
        """
        # 根据服务器类型选择 profile
        if server_type == 'login':
            profile = 'login_server_dev'
        else:
            profile = 'game_server_dev'
        
        cmd_map = {
            'all': f'{REBAR3_CMD} as {profile} compile',
            'code': f'{REBAR3_CMD} as {profile} compile',
            'proto': f'{REBAR3_CMD} protobuf compile',
            'table': f'{REBAR3_CMD} cache compile',
            'tbllog': f'{REBAR3_CMD} tbllog compile',
        }
        
        cmd = cmd_map.get(target, cmd_map['all'])
        
        type_name = '登录服' if server_type == 'login' else '游戏服'
        print(f"\n========== 编译 [{target}] ({type_name}) ==========")
        print(f"命令: {cmd}")
        
        process = run_cmd_foreground(cmd, self.server_root, f"compile-{target}")
        return_code = process.wait()
        
        if return_code == 0:
            print(f"✓ 编译成功")
        else:
            print(f"✗ 编译失败 (返回码: {return_code})")
        
        print("================================\n")
        return return_code == 0
    
    def interactive_menu(self):
        """交互式菜单"""
        print("\n" + "=" * 50)
        print("       Server Manager - 交互式模式")
        print("=" * 50)
        print(f"服务器根目录: {self.server_root}")
        print("=" * 50)
        
        while True:
            print("\n请选择操作:")
            print("  [1] 列出所有服务器")
            print("  [2] 创建服务器")
            print("  [3] 启动服务器")
            print("  [4] 停止服务器")
            print("  [5] 连接服务器")
            print("  [6] 编译代码")
            print("  [7] 重新生成 sys.config")
            print("  [0] 退出")
            print("")
            
            try:
                choice = input("请输入选项 [0-7]: ").strip()
            except (KeyboardInterrupt, EOFError):
                print("\n再见!")
                break
            
            if choice == '0':
                print("再见!")
                break
            elif choice == '1':
                self.list_servers()
            elif choice == '2':
                self._interactive_create_server()
            elif choice == '3':
                self._interactive_start_server()
            elif choice == '4':
                self._interactive_stop_server()
            elif choice == '5':
                self._interactive_connect_server()
            elif choice == '6':
                self._interactive_compile()
            elif choice == '7':
                self._interactive_regenerate_config()
            else:
                print("无效选项，请重新输入")
    
    def _interactive_create_server(self):
        """交互式创建服务器"""
        print("\n========== 创建服务器 ==========")
        print("服务器类型:")
        print("  [1] game   - 游戏服")
        print("  [2] login  - 登录服")
        print("  [3] center - 中心服")
        print("  [4] cross  - 跨服")
        print("  [5] client - 客户端测试服")
        
        try:
            type_choice = input("请选择类型 [1-5]: ").strip()
            type_map = {'1': 'game', '2': 'login', '3': 'center', '4': 'cross', '5': 'client'}
            server_type = type_map.get(type_choice)
            if not server_type:
                print("无效选项")
                return
            
            server_id = input(f"请输入服务器ID: ").strip()
            if not server_id.isdigit():
                print("无效的服务器ID")
                return
            server_id = int(server_id)
            
            prefix = input(f"请输入前缀 (默认: {self.prefix}): ").strip() or self.prefix
            
            # 可选参数
            tcp_port_str = input("请输入TCP端口 (留空使用默认): ").strip()
            tcp_port = int(tcp_port_str) if tcp_port_str.isdigit() else None
            
            http_port_str = input("请输入HTTP端口 (留空使用默认): ").strip()
            http_port = int(http_port_str) if http_port_str.isdigit() else None
            
            self.create_server_cmd(
                server_type=server_type,
                server_id=server_id,
                prefix=prefix,
                tcp_port=tcp_port,
                http_port=http_port
            )
        except (KeyboardInterrupt, EOFError):
            print("\n取消操作")
    
    def _interactive_start_server(self):
        """交互式启动服务器"""
        print("\n========== 启动服务器 ==========")
        
        # 列出可用服务器
        servers = get_server_list(self.run_dir)
        all_servers = []
        for server_list in servers.values():
            all_servers.extend(server_list)
        
        if not all_servers:
            print("没有可用的服务器")
            return
        
        print("可用服务器:")
        for i, server in enumerate(sorted(all_servers), 1):
            print(f"  [{i}] {server}")
        
        try:
            choice = input(f"请选择服务器 [1-{len(all_servers)}]: ").strip()
            if not choice.isdigit() or int(choice) < 1 or int(choice) > len(all_servers):
                print("无效选项")
                return
            
            server_name = sorted(all_servers)[int(choice) - 1]
            
            print("\n启动模式:")
            print("  [1] rebar3 shell (默认，支持热更新)")
            print("  [2] 快速启动 (直接用 erl，启动更快)")
            mode = input("请选择启动模式 [1]: ").strip()
            quick = mode == '2'
            
            print("\n运行方式:")
            print("  [1] 前台运行 (默认，当前窗口)")
            print("  [2] 后台运行 (新窗口)")
            run_mode = input("请选择运行方式 [1]: ").strip()
            background = run_mode == '2'
            
            self.start_server(
                server_name=server_name,
                use_rebar=not quick,
                foreground=not background
            )
        except (KeyboardInterrupt, EOFError):
            print("\n取消操作")
    
    def _interactive_stop_server(self):
        """交互式停止服务器"""
        print("\n========== 停止服务器 ==========")
        
        # 列出可用服务器
        servers = get_server_list(self.run_dir)
        all_servers = []
        for server_list in servers.values():
            all_servers.extend(server_list)
        
        if not all_servers:
            print("没有可用的服务器")
            return
        
        print("可用服务器:")
        for i, server in enumerate(sorted(all_servers), 1):
            print(f"  [{i}] {server}")
        
        try:
            choice = input(f"请选择服务器 [1-{len(all_servers)}]: ").strip()
            if not choice.isdigit() or int(choice) < 1 or int(choice) > len(all_servers):
                print("无效选项")
                return
            
            server_name = sorted(all_servers)[int(choice) - 1]
            self.stop_server(server_name)
        except (KeyboardInterrupt, EOFError):
            print("\n取消操作")
    
    def _interactive_connect_server(self):
        """交互式连接服务器"""
        print("\n========== 连接服务器 ==========")
        
        # 列出可用服务器
        servers = get_server_list(self.run_dir)
        all_servers = []
        for server_list in servers.values():
            all_servers.extend(server_list)
        
        if not all_servers:
            print("没有可用的服务器")
            return
        
        print("可用服务器:")
        for i, server in enumerate(sorted(all_servers), 1):
            print(f"  [{i}] {server}")
        
        try:
            choice = input(f"请选择服务器 [1-{len(all_servers)}]: ").strip()
            if not choice.isdigit() or int(choice) < 1 or int(choice) > len(all_servers):
                print("无效选项")
                return
            
            server_name = sorted(all_servers)[int(choice) - 1]
            target_ip = input("请输入目标IP (留空使用本机): ").strip() or None
            
            self.connect_server(server_name, target_ip)
        except (KeyboardInterrupt, EOFError):
            print("\n取消操作")
    
    def _interactive_compile(self):
        """交互式编译"""
        print("\n========== 编译代码 ==========")
        
        print("\n服务器类型:")
        print("  [1] 游戏服 (game_server_dev)")
        print("  [2] 登录服 (login_server_dev)")
        
        try:
            type_choice = input("请选择服务器类型 [1]: ").strip()
            server_type = 'login' if type_choice == '2' else 'game'
            
            print("\n编译目标:")
            print("  [1] all    - 编译所有")
            print("  [2] code   - 编译代码")
            print("  [3] proto  - 编译协议")
            print("  [4] table  - 编译配置表")
            print("  [5] tbllog - 编译日志表")
            
            choice = input("请选择目标 [1-5]: ").strip()
            target_map = {'1': 'all', '2': 'code', '3': 'proto', '4': 'table', '5': 'tbllog'}
            target = target_map.get(choice, 'all')
            
            self.compile(target, server_type)
        except (KeyboardInterrupt, EOFError):
            print("\n取消操作")
    
    def _interactive_regenerate_config(self):
        """交互式重新生成 sys.config"""
        print("\n========== 重新生成 sys.config ==========")
        
        # 列出可用服务器
        servers = get_server_list(self.run_dir)
        all_servers = []
        for server_list in servers.values():
            all_servers.extend(server_list)
        
        if not all_servers:
            print("没有可用的服务器")
            return
        
        print("可用服务器:")
        for i, server in enumerate(sorted(all_servers), 1):
            print(f"  [{i}] {server}")
        
        try:
            choice = input(f"请选择服务器 [1-{len(all_servers)}]: ").strip()
            if not choice.isdigit() or int(choice) < 1 or int(choice) > len(all_servers):
                print("无效选项")
                return
            
            server_name = sorted(all_servers)[int(choice) - 1]
            self.regenerate_config(server_name)
        except (KeyboardInterrupt, EOFError):
            print("\n取消操作")
