from __future__ import annotations
import tkinter as tk
from tkinter import (
    scrolledtext, ttk, font, messagebox, filedialog, simpledialog
)
import re
import os
import ast
from typing import List, Dict, Any, Optional, Tuple, Set, Generator
import operator
from collections import OrderedDict
import threading
import time
import queue

# ====================== 1. 全局主题配置 ======================
class Theme:
    def __init__(self):
        self.light_theme: Dict[str, str] = {
            'bg': '#f0f0f0', 'code_bg': '#ffffff', 'line_bg': '#e8e8e8',
            'text_fg': '#222222', 'line_fg': '#666666', 'sidebar_bg': '#f5f5f5',
            'keyword': '#0000ff', 'string': '#800080', 'number': '#ff0000',
            'comment': '#008000', 'error': '#ff0000', 'success': '#008000',
            'copyright': '#666666', 'warning': '#ff9900'
        }
        self.dark_theme: Dict[str, str] = {
            'bg': '#f0f0f0', 'code_bg': '#1e1e1e', 'line_bg': '#2d2d2d',
            'text_fg': '#ffffff', 'line_fg': '#cccccc', 'sidebar_bg': '#f5f5f5',
            'keyword': '#569cd6', 'string': '#d69d85', 'number': '#b5cea8',
            'comment': '#6a9955', 'error': '#ff6b6b', 'success': '#4ade80',
            'copyright': '#666666', 'warning': '#ffd700'
        }
        self.current_theme: Dict[str, str] = self.light_theme
        self.is_dark_mode: bool = False

    def toggle_theme(self) -> Dict[str, str]:
        self.is_dark_mode = not self.is_dark_mode
        self.current_theme = self.dark_theme if self.is_dark_mode else self.light_theme
        return self.current_theme

    def get_current_theme(self) -> Dict[str, str]:
        return self.current_theme

theme_manager: Theme = Theme()

# ====================== 2. 带行号的代码编辑框 ======================
class LineNumberText(tk.Frame):
    def __init__(self, parent: tk.Widget, **kwargs: Any):
        self.font: font.Font = kwargs.pop('font', font.Font(family='Consolas', size=11))
        code_bg: str = kwargs.pop('code_bg', theme_manager.get_current_theme()['code_bg'])
        text_fg: str = kwargs.pop('text_fg', theme_manager.get_current_theme()['text_fg'])
        insertbackground: str = kwargs.pop('insertbackground', theme_manager.get_current_theme()['text_fg'])
        line_bg: str = kwargs.pop('line_bg', theme_manager.get_current_theme()['line_bg'])
        line_fg: str = kwargs.pop('line_fg', theme_manager.get_current_theme()['line_fg'])
        
        super().__init__(parent, **kwargs)
        
        self.line_numbers: tk.Text = tk.Text(
            self, width=4, padx=3, takefocus=0, border=0, wrap=tk.NONE,
            state=tk.DISABLED, font=self.font, bg=line_bg, fg=line_fg
        )
        self.line_numbers.pack(side=tk.LEFT, fill=tk.Y)
        
        self.text: scrolledtext.ScrolledText = scrolledtext.ScrolledText(
            self, wrap=tk.NONE, font=self.font, bg=code_bg,
            fg=text_fg, insertbackground=insertbackground, undo=True
        )
        self.text.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
        
        # 优化：避免频繁更新行号
        self._last_line_count: int = 0
        self._update_timer: Optional[str] = None
        
        self.text.bind('<Configure>', lambda e: self.schedule_update_line_numbers())
        self.text.bind('<KeyRelease>', lambda e: self.schedule_update_line_numbers())
        self.text.bind('<MouseWheel>', lambda e: self.schedule_update_line_numbers())
        self.text.bind('<Button-1>', lambda e: self.schedule_update_line_numbers())
        
        self._update_line_numbers()

    def schedule_update_line_numbers(self, delay: int = 50) -> None:
        """延迟更新行号，避免频繁刷新"""
        if self._update_timer:
            self.after_cancel(self._update_timer)
        self._update_timer = self.after(delay, self._update_line_numbers)

    def _update_line_numbers(self, event: Optional[tk.Event] = None) -> None:
        """增量更新行号，只当行数变化时重新生成"""
        num_lines: int = int(self.text.index('end-1c').split('.')[0])
        
        # 只有当行数变化时才重新生成行号文本
        if num_lines != self._last_line_count:
            self._last_line_count = num_lines
            line_text: str = '\n'.join(str(i) for i in range(1, num_lines + 1))
            
            self.line_numbers.config(state=tk.NORMAL)
            self.line_numbers.delete('1.0', tk.END)
            self.line_numbers.insert('1.0', line_text)
            self.line_numbers.config(state=tk.DISABLED)
        
        # 同步滚动位置
        self.line_numbers.yview_moveto(self.text.yview()[0])
        self._update_timer = None

    def get(self, *args: Any, **kwargs: Any) -> str:
        return self.text.get(*args, **kwargs)

    def delete(self, *args: Any, **kwargs: Any) -> None:
        self.text.delete(*args, **kwargs)

    def insert(self, *args: Any, **kwargs: Any) -> None:
        self.text.insert(*args, **kwargs)

    def configure(self, **kwargs: Any) -> None:
        if 'bg' in kwargs:
            self.line_numbers.config(bg=kwargs['bg'])
            del kwargs['bg']
        if 'fg' in kwargs:
            self.line_numbers.config(fg=kwargs['fg'])
            del kwargs['fg']
        if 'code_bg' in kwargs:
            self.text.config(bg=kwargs['code_bg'])
            del kwargs['code_bg']
        if 'text_fg' in kwargs:
            self.text.config(fg=kwargs['text_fg'])
            del kwargs['text_fg']
        if 'insertbackground' in kwargs:
            self.text.config(insertbackground=kwargs['insertbackground'])
            del kwargs['insertbackground']
        super().configure(**kwargs)

    def tag_config(self, *args: Any, **kwargs: Any) -> None:
        self.text.tag_config(*args, **kwargs)

    def tag_remove(self, *args: Any, **kwargs: Any) -> None:
        self.text.tag_remove(*args, **kwargs)

    def tag_add(self, *args: Any, **kwargs: Any) -> None:
        self.text.tag_add(*args, **kwargs)

# ====================== 3. 增强的表达式计算引擎 ======================
class ExprCalculator:
    def __init__(self, interpreter: 'KoalaInterpreter'):
        self.interpreter: 'KoalaInterpreter' = interpreter
        # 安全字符白名单，支持更广泛的运算符
        self.safe_pattern: re.Pattern = re.compile(r'^[a-zA-Z0-9_+\-*/%^<>=!|&().\s]+$')
        # 运算符映射
        self.op_replace_map: List[Tuple[str, str]] = [
            ('||', 'or'),
            ('&&', 'and'),
            ('^', '**'),
            ('==', '=='),
            ('!=', '!='),
            ('<=', '<='),
            ('>=', '>=')
        ]
        # 表达式结果缓存
        self._cache: OrderedDict[str, Any] = OrderedDict()
        self._cache_limit: int = 1000
        
    def calculate(self, expr: str, variables: Dict[str, Any]) -> Any:
        """安全计算表达式，支持缓存和安全检查"""
        expr = expr.strip()
        if not expr:
            raise Exception("空表达式")
        
        # 创建缓存键
        cache_key = f"{expr}|{self._hash_variables(variables)}"
        
        # 检查缓存
        if cache_key in self._cache:
            return self._cache[cache_key]
        
        # 1. 安全校验
        if not self.safe_pattern.match(expr):
            raise Exception(f"表达式包含非法字符：{expr}")
        
        # 2. AST安全检查
        self._ast_check_safety(expr)
        
        # 3. 运算符替换
        processed_expr = expr
        for old_op, new_op in self.op_replace_map:
            processed_expr = processed_expr.replace(old_op, new_op)
        
        # 4. 安全命名空间
        safe_namespace: Dict[str, Any] = {
            '__builtins__': {},
            'abs': abs, 'round': round, 'len': len,
            'int': int, 'float': float, 'str': str,
            'bool': bool, 'max': max, 'min': min,
            'sum': sum, 'input': self._safe_input,
            'None': None, 'True': True, 'False': False
        }
        safe_namespace.update(variables)
        
        # 5. 执行计算
        try:
            result = eval(processed_expr, safe_namespace)
        except NameError as e:
            raise Exception(f"变量未定义：{str(e).split()[-1]}")
        except SyntaxError as e:
            raise Exception(f"表达式语法错误：{expr}，{e}")
        except ZeroDivisionError:
            raise Exception("除零错误")
        except OverflowError:
            raise Exception("数值溢出错误")
        except TypeError as e:
            raise Exception(f"类型错误：{e}")
        except Exception as e:
            raise Exception(f"表达式计算失败：{expr}，{str(e)}")
        
        # 6. 布尔值统一转为1/0
        if isinstance(result, bool):
            result = 1 if result else 0
        
        # 7. 缓存结果
        self._add_to_cache(cache_key, result)
        return result
    
    def _safe_input(self, prompt: str = "") -> str:
        """安全输入函数，在主线程中弹出输入对话框"""
        if self.interpreter.root_window is None:
            return ""
        
        # 使用队列在主线程和后台线程之间通信
        input_queue = queue.Queue()
        
        def get_input_dialog():
            """在主线程中弹出输入对话框"""
            try:
                result = simpledialog.askstring("输入", prompt or "请输入：")
                input_queue.put(result if result is not None else "")
            except Exception as e:
                input_queue.put(f"输入错误: {str(e)}")
        
        # 强制在主线程中执行对话框弹出
        if threading.current_thread() is threading.main_thread():
            get_input_dialog()
        else:
            self.interpreter.root_window.after(0, get_input_dialog)
        
        # 等待输入结果
        try:
            result = input_queue.get(timeout=60)
            return result
        except queue.Empty:
            return ""
        except Exception as e:
            return f"输入异常: {str(e)}"
    
    def _hash_variables(self, variables: Dict[str, Any]) -> int:
        """为变量字典生成哈希值"""
        try:
            return hash(frozenset((k, str(v)) for k, v in variables.items()))
        except:
            return 0
    
    def _ast_check_safety(self, expr: str) -> None:
        """使用AST检查表达式的安全性"""
        try:
            tree = ast.parse(expr, mode='eval')
            for node in ast.walk(tree):
                if isinstance(node, ast.Call):
                    allowed_funcs = ['abs', 'round', 'len', 'int', 'float', 'str', 'bool', 'max', 'min', 'sum', 'input']
                    if isinstance(node.func, ast.Name) and node.func.id in allowed_funcs:
                        continue
                    raise Exception("不允许的函数调用")
                if isinstance(node, ast.Attribute):
                    raise Exception("不允许的属性访问")
                if isinstance(node, ast.Lambda):
                    raise Exception("不允许的Lambda表达式")
                if isinstance(node, (ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp)):
                    raise Exception("不允许的理解表达式")
        except SyntaxError as e:
            raise Exception(f"表达式语法错误：{expr}，{e}")
    
    def _add_to_cache(self, key: str, value: Any) -> None:
        """添加结果到缓存（LRU策略）"""
        if key in self._cache:
            self._cache.move_to_end(key)
        else:
            self._cache[key] = value
            if len(self._cache) > self._cache_limit:
                self._cache.popitem(last=False)
    
    def clear_cache(self) -> None:
        """清空缓存"""
        self._cache.clear()

# ====================== 4. 实时语法高亮功能 ======================
def highlight_syntax_realtime(code_editor: LineNumberText) -> None:
    """实时语法高亮"""
    theme = theme_manager.get_current_theme()
    
    # 清除所有高亮标签
    for tag in ['keyword', 'string', 'number', 'comment', 'class', 'control', 'array', 'logic']:
        code_editor.tag_remove(tag, '1.0', tk.END)
    
    # 获取所有文本
    try:
        all_text = code_editor.get('1.0', tk.END)
        lines = all_text.split('\n')
        
        for line_num, line in enumerate(lines, 1):
            if line_num > 1000:
                break
                
            # 逻辑运算符高亮
            logic_matches: List[str] = re.findall(r'\|\||&&', line)
            for match in logic_matches:
                start_idx: int = line.find(match)
                while start_idx != -1:
                    code_editor.tag_add('logic', f"{line_num}.{start_idx}", f"{line_num}.{start_idx + len(match)}")
                    start_idx = line.find(match, start_idx + len(match))
            
            # 数组下标
            array_matches: List[str] = re.findall(r'\[[^\]]+\]', line)
            for match in array_matches:
                start_idx: int = line.find(match)
                if start_idx != -1:
                    code_editor.tag_add('array', f"{line_num}.{start_idx}", f"{line_num}.{start_idx + len(match)}")
            
            # 控制结构
            for keyword in ['if', 'for', 'else', 'while', 'do', 'switch', 'case']:
                pattern = r'\b' + re.escape(keyword) + r'\b'
                for match in re.finditer(pattern, line):
                    code_editor.tag_add('control', f"{line_num}.{match.start()}", f"{line_num}.{match.end()}")
            
            # 普通关键字
            for keyword in ['class', 'new', 'output', 'input', 'self', 'return', 'function', 'var', 'let', 'const']:
                pattern = r'\b' + re.escape(keyword) + r'\b'
                for match in re.finditer(pattern, line):
                    code_editor.tag_add('keyword', f"{line_num}.{match.start()}", f"{line_num}.{match.end()}")
            
            # 类名
            if line.startswith('class '):
                class_match = re.match(r'class\s+([a-zA-Z_][a-zA-Z0-9_]*)', line)
                if class_match:
                    class_name = class_match.group(1)
                    start_idx = line.find(class_name)
                    if start_idx != -1:
                        code_editor.tag_add('class', f"{line_num}.{start_idx}", f"{line_num}.{start_idx + len(class_name)}")
            
            # 字符串
            string_matches: List[str] = re.findall(r'"[^"]*"|\'[^\']*\'', line)
            for match in string_matches:
                start_idx: int = line.find(match)
                if start_idx != -1:
                    code_editor.tag_add('string', f"{line_num}.{start_idx}", f"{line_num}.{start_idx + len(match)}")
            
            # 数字
            number_matches: List[str] = re.findall(r'\b\d+\.?\d*\b', line)
            for match in number_matches:
                start_idx: int = line.find(match)
                if start_idx != -1:
                    code_editor.tag_add('number', f"{line_num}.{start_idx}", f"{line_num}.{start_idx + len(match)}")
            
            # 注释
            comment_start: int = line.find('//')
            if comment_start != -1:
                code_editor.tag_add('comment', f"{line_num}.{comment_start}", f"{line_num}.{len(line)}")
        
        # 设置高亮样式
        code_editor.tag_config('keyword', foreground=theme['keyword'], font=('Consolas', 11, 'bold'))
        code_editor.tag_config('control', foreground='#ff79c6', font=('Consolas', 11, 'bold'))
        code_editor.tag_config('class', foreground='#4ec9b0', font=('Consolas', 11, 'bold'))
        code_editor.tag_config('array', foreground='#f1fa8c', font=('Consolas', 11, 'bold'))
        code_editor.tag_config('logic', foreground='#bd93f9', font=('Consolas', 11, 'bold'))
        code_editor.tag_config('string', foreground=theme['string'])
        code_editor.tag_config('number', foreground=theme['number'])
        code_editor.tag_config('comment', foreground=theme['comment'])
        
    except Exception as e:
        pass

# ====================== 5. Koala语言解释器 ======================
class KoalaInterpreter:
    def __init__(self, root_window: Optional[tk.Tk] = None):
        self.variables: Dict[str, Any] = {}
        self.classes: Dict[str, Any] = {}
        self.instances: Dict[str, Any] = {}
        self.calculator: ExprCalculator = ExprCalculator(self)
        self.root_window = root_window
        
        # 正则模式
        self.assign_pattern: re.Pattern = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*(\s*\[[^\]]+\])?\s*=.*$')
        self.array_assign_pattern: re.Pattern = re.compile(r'^([a-zA-Z_][a-zA-Z0-9_]*)\s*\[([^\]]+)\]\s*=(.*)$')
        self.array_literal_pattern: re.Pattern = re.compile(r'^\[(.*)\]$')
        self.if_pattern: re.Pattern = re.compile(r'^if\s*\((.*)\)\s*\{?$')
        self.if_else_pattern: re.Pattern = re.compile(r'^else\s*(if\s*\((.*)\))?\s*\{?$')
        self.for_pattern: re.Pattern = re.compile(r'^for\s*\((.*);(.*);(.*)\)\s*\{?$')
        self.while_pattern: re.Pattern = re.compile(r'^while\s*\((.*)\)\s*\{?$')
        self.var_name_pattern: re.Pattern = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$')
        
        # 执行统计
        self.execution_stats = {
            'total_lines': 0,
            'executed_lines': 0,
            'variables_created': 0,
            'arrays_created': 0,
            'instances_created': 0,
            'start_time': 0,
            'end_time': 0
        }

    def execute_code(self, code: str) -> str:
        """执行代码，增强错误处理"""
        self.execution_stats['start_time'] = time.time()
        self.execution_stats['total_lines'] = len(code.strip().split('\n'))
        self.execution_stats['executed_lines'] = 0
        
        # 重置统计
        self.execution_stats['variables_created'] = 0
        self.execution_stats['arrays_created'] = 0
        self.execution_stats['instances_created'] = 0
        
        output_lines: List[str] = []
        lines: List[str] = code.strip().split('\n')
        
        # 代码预处理
        processed_lines: List[str] = []
        for line in lines:
            # 移除注释
            line = line.split('//')[0].strip()
            # 去除行尾分号
            line = line.rstrip(';').strip()
            if line:
                processed_lines.append(line)
        
        # 执行代码
        try:
            result: str = self._execute_lines(processed_lines, output_lines)
            if "错误" in result:
                return result
        except MemoryError:
            return "❌ 内存不足：程序占用过多内存"
        except RecursionError:
            return "❌ 递归深度过大：请检查循环逻辑"
        except KeyboardInterrupt:
            return "⏹️ 执行被用户中断"
        except Exception as e:
            return f"❌ 未知错误：{type(e).__name__}: {str(e)}"
        finally:
            self.execution_stats['end_time'] = time.time()
        
        # 添加执行统计
        if output_lines:
            output_lines.append(f"\n📊 执行统计:")
            output_lines.append(f"   执行行数: {self.execution_stats['executed_lines']}/{self.execution_stats['total_lines']}")
            output_lines.append(f"   创建变量: {self.execution_stats['variables_created']}")
            output_lines.append(f"   创建数组: {self.execution_stats['arrays_created']}")
            output_lines.append(f"   创建实例: {self.execution_stats['instances_created']}")
            execution_time = self.execution_stats['end_time'] - self.execution_stats['start_time']
            output_lines.append(f"   执行时间: {execution_time:.3f}秒")
            output_lines.append(f"   缓存命中: {len(self.calculator._cache)} 个表达式")
        
        return '\n'.join(output_lines) if output_lines else "无输出内容"

    def _execute_lines(self, lines: List[str], output_lines: List[str], line_offset: int = 0, in_else: bool = False) -> str:
        """执行多行代码，支持嵌套和else语句"""
        line_index: int = 0
        total_lines: int = len(lines)
        
        while line_index < total_lines:
            current_line: str = lines[line_index]
            line_num: int = line_index + 1 + line_offset
            self.execution_stats['executed_lines'] += 1
            
            try:
                # 1. 处理if选择结构
                if_match = self.if_pattern.match(current_line)
                if if_match:
                    cond_expr: str = if_match.group(1).strip()
                    block_end: int = self._find_block_end(lines, line_index)
                    
                    if block_end == -1:
                        return f"第{line_num}行错误：if语句缺少闭合的}}"
                    
                    # 计算条件
                    cond_result: Any = self.calculator.calculate(cond_expr, self.variables)
                    
                    # 查找else分支
                    else_block_start = -1
                    else_block_end = -1
                    
                    # 检查是否有else或else if
                    for i in range(block_end + 1, total_lines):
                        if lines[i].strip() == '}' and i > block_end:
                            break
                        if self.if_else_pattern.match(lines[i]):
                            else_block_start = i
                            else_block_end = self._find_block_end(lines, i)
                            break
                    
                    if cond_result != 0:
                        # 执行if块
                        block_lines: List[str] = lines[line_index+1 : block_end]
                        block_result: str = self._execute_lines(block_lines, output_lines, line_num)
                        if "错误" in block_result:
                            return block_result
                        
                        # 跳过else块
                        if else_block_start != -1 and else_block_end != -1:
                            line_index = else_block_end + 1
                        else:
                            line_index = block_end + 1
                    else:
                        # 条件为假，跳过if块
                        if else_block_start != -1 and else_block_end != -1:
                            # 执行else块
                            else_lines: List[str] = lines[else_block_start+1 : else_block_end]
                            else_result: str = self._execute_lines(else_lines, output_lines, line_num, in_else=True)
                            if "错误" in else_result:
                                return else_result
                            line_index = else_block_end + 1
                        else:
                            line_index = block_end + 1
                    continue
                
                # 2. 处理for循环结构
                elif self.for_pattern.match(current_line):
                    for_match: Optional[re.Match] = self.for_pattern.match(current_line)
                    init_expr: str = for_match.group(1).strip()
                    cond_expr: str = for_match.group(2).strip()
                    step_expr: str = for_match.group(3).strip()
                    block_end: int = self._find_block_end(lines, line_index)
                    
                    if block_end == -1:
                        return f"第{line_num}行错误：for语句缺少闭合的}}"
                    
                    # 执行循环初始化
                    if init_expr:
                        init_result: str = self._execute_single_line(init_expr, output_lines)
                        if init_result and "错误" in init_result:
                            return f"第{line_num}行{init_result}"
                    
                    # 循环执行
                    loop_count: int = 0
                    max_loop: int = 10000000
                    block_lines: List[str] = lines[line_index+1 : block_end]
                    
                    while True:
                        if loop_count >= max_loop:
                            output_lines.append("⚠️ 警告：循环超过1000万次，已自动停止")
                            break
                        
                        # 计算循环条件
                        try:
                            cond_result: Any = self.calculator.calculate(cond_expr, self.variables)
                        except Exception as e:
                            return f"第{line_num}行循环条件错误：{str(e)}"
                        
                        if cond_result == 0:
                            break
                        
                        # 执行循环体
                        block_result: str = self._execute_lines(block_lines, output_lines, line_num)
                        if "错误" in block_result:
                            return block_result
                        
                        # 执行循环步长
                        if step_expr:
                            step_result: str = self._execute_single_line(step_expr, output_lines)
                            if step_result and "错误" in step_result:
                                return f"第{line_num}行{step_result}"
                        
                        loop_count += 1
                    
                    line_index = block_end + 1
                    continue
                
                # 3. 处理while循环
                elif self.while_pattern.match(current_line):
                    while_match: Optional[re.Match] = self.while_pattern.match(current_line)
                    cond_expr: str = while_match.group(1).strip()
                    block_end: int = self._find_block_end(lines, line_index)
                    
                    if block_end == -1:
                        return f"第{line_num}行错误：while语句缺少闭合的}}"
                    
                    # 循环执行
                    loop_count: int = 0
                    max_loop: int = 10000000
                    block_lines: List[str] = lines[line_index+1 : block_end]
                    
                    while True:
                        if loop_count >= max_loop:
                            output_lines.append("⚠️ 警告：循环超过1000万次，已自动停止")
                            break
                        
                        # 计算循环条件
                        try:
                            cond_result: Any = self.calculator.calculate(cond_expr, self.variables)
                        except Exception as e:
                            return f"第{line_num}行循环条件错误：{str(e)}"
                        
                        if cond_result == 0:
                            break
                        
                        # 执行循环体
                        block_result: str = self._execute_lines(block_lines, output_lines, line_num)
                        if "错误" in block_result:
                            return block_result
                        
                        loop_count += 1
                    
                    line_index = block_end + 1
                    continue
                
                # 4. 忽略单独的括号
                elif current_line == '{' or current_line == '}':
                    line_index += 1
                    continue
                
                # 5. 处理else/else if
                elif self.if_else_pattern.match(current_line) and not in_else:
                    block_end = self._find_block_end(lines, line_index)
                    if block_end != -1:
                        line_index = block_end + 1
                    else:
                        line_index += 1
                    continue
                
                # 6. 执行单行语句
                else:
                    line_result: str = self._execute_single_line(current_line, output_lines)
                    if line_result and "错误" in line_result:
                        return f"第{line_num}行{line_result}"
                    line_index += 1
                    
            except Exception as e:
                return f"第{line_num}行执行错误：{str(e)}"
        
        return ""

    def _find_block_end(self, lines: List[str], start_index: int) -> int:
        """找到代码块的闭合}，支持嵌套"""
        brace_count: int = 0
        for i in range(start_index, len(lines)):
            line: str = lines[i]
            brace_count += line.count('{')
            brace_count -= line.count('}')
            if brace_count == 0 and i > start_index:
                return i
        return -1

    def _execute_single_line(self, line: str, output_lines: List[str]) -> Optional[str]:
        """执行单行语句"""
        try:
            # 1. 类定义
            if line.startswith('class '):
                return self._handle_class_definition(line, output_lines)
            
            # 2. 对象实例化
            elif ' = new ' in line:
                return self._handle_instance_creation(line, output_lines)
            
            # 3. 数组下标赋值
            elif self.array_assign_pattern.match(line):
                return self._handle_array_assignment(line, output_lines)
            
            # 4. 普通变量/数组赋值
            elif self.assign_pattern.match(line):
                return self._handle_variable_assignment(line, output_lines)
            
            # 5. 实例属性赋值
            elif '.' in line and '=' in line and '()' not in line:
                return self._handle_instance_assignment(line, output_lines)
            
            # 6. 输出语句
            elif line.startswith('output'):
                return self._handle_output(line, output_lines)
            
            # 7. 方法调用
            elif '()' in line and '.' in line:
                return self._handle_method_call(line, output_lines)
            
            # 8. 函数定义
            elif line.startswith('function '):
                return self._handle_function_definition(line, output_lines)
            
            # 9. 返回语句
            elif line.startswith('return '):
                return self._handle_return(line, output_lines)
            
            # 10. 未知语句
            else:
                # 检查是否为表达式计算
                try:
                    result = self.calculator.calculate(line, self.variables)
                    output_lines.append(f"表达式结果: {result}")
                    return None
                except:
                    return f"错误：不支持的语句 '{line}'"
                
        except Exception as e:
            return f"执行错误：{str(e)}"

    def _handle_class_definition(self, line: str, output_lines: List[str]) -> Optional[str]:
        """处理类定义"""
        class_name: str = line.split('class ')[1].split('{')[0].strip()
        if not self.var_name_pattern.match(class_name):
            return f"错误：类名{class_name}不合法"
        self.classes[class_name] = {'methods': {}, 'attrs': [], 'static_methods': {}}
        output_lines.append(f"✅ 定义类 {class_name}")
        return None

    def _handle_instance_creation(self, line: str, output_lines: List[str]) -> Optional[str]:
        """处理对象实例化"""
        var_name, class_name = line.split(' = new ')
        var_name = var_name.strip()
        class_name = class_name.strip().rstrip('{')
        if not self.var_name_pattern.match(var_name):
            return f"错误：变量名{var_name}不合法"
        if class_name not in self.classes:
            return f"错误：类{class_name}未定义"
        self.instances[var_name] = {
            'class': class_name, 
            'attrs': {},
            'methods': self.classes[class_name]['methods'].copy()
        }
        output_lines.append(f"✅ 创建 {class_name} 实例 {var_name}")
        self.execution_stats['instances_created'] += 1
        return None

    def _handle_array_assignment(self, line: str, output_lines: List[str]) -> Optional[str]:
        """处理数组下标赋值"""
        match: Optional[re.Match] = self.array_assign_pattern.match(line)
        array_name: str = match.group(1).strip()
        index_expr: str = match.group(2).strip()
        value_expr: str = match.group(3).strip()
        
        if array_name not in self.variables:
            return f"错误：数组{array_name}未定义"
        
        array: Any = self.variables[array_name]
        if not isinstance(array, list):
            return f"错误：{array_name}不是数组类型"
        
        index: int = int(self.calculator.calculate(index_expr, self.variables))
        value: Any = self._parse_value(value_expr)
        
        if index < 0 or index >= len(array):
            return f"错误：数组下标越界：{array_name}[{index}]，数组长度：{len(array)}"
        
        array[index] = value
        return None

    def _handle_variable_assignment(self, line: str, output_lines: List[str]) -> Optional[str]:
        """处理变量赋值"""
        var_name, value_expr = line.split('=', 1)
        var_name = var_name.strip()
        value_expr = value_expr.strip()
        
        # 检查是否是数组字面量赋值
        if '[' in var_name and ']' in var_name:
            array_match = re.match(r'([a-zA-Z_][a-zA-Z0-9_]*)\s*\[\s*(\d+)\s*\]', var_name)
            if array_match:
                array_name = array_match.group(1)
                array_size = int(array_match.group(2))
                if not self.var_name_pattern.match(array_name):
                    return f"错误：数组名{array_name}不合法"
                value: Any = self._parse_value(value_expr)
                self.variables[array_name] = [value] * array_size
                self.execution_stats['arrays_created'] += 1
                return None
        
        if not self.var_name_pattern.match(var_name):
            return f"错误：变量名{var_name}不合法"
        
        # 检查是否为新变量
        is_new_var = var_name not in self.variables
        
        value: Any = self._parse_value(value_expr)
        self.variables[var_name] = value
        
        if is_new_var:
            self.execution_stats['variables_created'] += 1
        
        return None

    def _handle_instance_assignment(self, line: str, output_lines: List[str]) -> Optional[str]:
        """处理实例属性赋值"""
        inst_attr, value_expr = line.split('=', 1)
        inst_name, attr_name = inst_attr.split('.')
        inst_name = inst_name.strip()
        attr_name = attr_name.strip()
        value: Any = self._parse_value(value_expr.strip())
        
        if inst_name not in self.instances:
            return f"错误：实例{inst_name}未定义"
        
        self.instances[inst_name]['attrs'][attr_name] = value
        return None

    def _handle_output(self, line: str, output_lines: List[str]) -> Optional[str]:
        """处理输出语句"""
        match: Optional[re.Match] = re.search(r'output\((.*)\)', line)
        if not match:
            return f"错误：output格式错误，正确示例：output(\"hello\")"
        
        args_str: str = match.group(1).strip()
        args: List[str] = self._parse_output_args(args_str)
        output_parts: List[str] = []
        
        for arg in args:
            arg = arg.strip()
            if not arg:
                continue
            
            # 字符串字面量
            if (arg.startswith('"') and arg.endswith('"')) or (arg.startswith("'") and arg.endswith("'")):
                output_parts.append(arg[1:-1])
            
            # 实例属性
            elif '.' in arg and not re.search(r'[+\-*/%^<>=!|&()\[\]]', arg):
                inst_name, attr_name = arg.split('.')
                inst_name = inst_name.strip()
                attr_name = attr_name.strip()
                if inst_name in self.instances and attr_name in self.instances[inst_name]['attrs']:
                    output_parts.append(str(self.instances[inst_name]['attrs'][attr_name]))
                else:
                    output_parts.append(arg)
            
            # 表达式/变量/数组
            else:
                try:
                    result: Any = self.calculator.calculate(arg, self.variables)
                    output_parts.append(str(result))
                except:
                    output_parts.append(arg)
        
        output_lines.append(' '.join(output_parts))
        return None

    def _handle_method_call(self, line: str, output_lines: List[str]) -> Optional[str]:
        """处理方法调用"""
        inst_name, method = line.split('.')
        inst_name = inst_name.strip()
        method_name: str = method.split('()')[0].strip()
        
        if inst_name not in self.instances:
            return f"错误：实例{inst_name}未定义"
        
        output_lines.append(f"✅ 调用 {inst_name}.{method_name}()")
        return None

    def _handle_function_definition(self, line: str, output_lines: List[str]) -> Optional[str]:
        """处理函数定义（占位符）"""
        func_name = line.split('function ')[1].split('(')[0].strip()
        output_lines.append(f"✅ 定义函数 {func_name}()")
        return None

    def _handle_return(self, line: str, output_lines: List[str]) -> Optional[str]:
        """处理返回语句（占位符）"""
        return_expr = line.split('return ')[1].strip()
        try:
            result = self.calculator.calculate(return_expr, self.variables)
            output_lines.append(f"↩️ 返回: {result}")
        except:
            output_lines.append(f"↩️ 返回: {return_expr}")
        return None

    def _parse_output_args(self, args_str: str) -> List[str]:
        """解析output的参数，处理字符串内的逗号"""
        args: List[str] = []
        current_arg: str = ''
        in_string: bool = False
        string_char: str = ''
        
        for char in args_str:
            if char in ('"', "'"):
                if in_string and char == string_char:
                    in_string = False
                    string_char = ''
                elif not in_string:
                    in_string = True
                    string_char = char
                current_arg += char
            elif char == ',' and not in_string:
                args.append(current_arg.strip())
                current_arg = ''
            else:
                current_arg += char
        
        if current_arg.strip():
            args.append(current_arg.strip())
        
        return args

    def _parse_value(self, value_expr: str) -> Any:
        """解析值，支持数组、字符串、数字、表达式"""
        value_expr = value_expr.strip()
        
        # 1. 检查是否是input函数调用
        if value_expr.startswith('input(') and value_expr.endswith(')'):
            prompt = value_expr[6:-1].strip()
            if (prompt.startswith('"') and prompt.endswith('"')) or (prompt.startswith("'") and prompt.endswith("'")):
                prompt = prompt[1:-1]
            return self.calculator._safe_input(prompt)
        
        # 2. 数组字面量 - 修复数组解析
        if value_expr.startswith('[') and value_expr.endswith(']'):
            content = value_expr[1:-1].strip()
            if not content:
                return []
            
            # 解析数组元素
            elements = []
            current_element = []
            in_string = False
            string_char = ''
            bracket_depth = 0
            
            i = 0
            while i < len(content):
                ch = content[i]
                
                if ch in ('"', "'"):
                    if not in_string:
                        in_string = True
                        string_char = ch
                        current_element.append(ch)
                    elif ch == string_char:
                        # 检查转义
                        if i > 0 and content[i-1] == '\\':
                            current_element.append(ch)
                        else:
                            in_string = False
                            string_char = ''
                            current_element.append(ch)
                    else:
                        current_element.append(ch)
                elif ch == '[' and not in_string:
                    bracket_depth += 1
                    current_element.append(ch)
                elif ch == ']' and not in_string:
                    bracket_depth -= 1
                    current_element.append(ch)
                elif ch == ',' and not in_string and bracket_depth == 0:
                    elem_str = ''.join(current_element).strip()
                    if elem_str:
                        elements.append(elem_str)
                    current_element = []
                else:
                    current_element.append(ch)
                
                i += 1
            
            # 处理最后一个元素
            if current_element:
                elem_str = ''.join(current_element).strip()
                if elem_str:
                    elements.append(elem_str)
            
            # 解析每个元素
            array = []
            for elem in elements:
                elem = elem.strip()
                if not elem:
                    continue
                
                # 递归解析每个元素
                array.append(self._parse_value(elem))
            
            self.execution_stats['arrays_created'] += 1
            return array
        
        # 3. 字符串字面量
        if (value_expr.startswith('"') and value_expr.endswith('"')) or (value_expr.startswith("'") and value_expr.endswith("'")):
            return value_expr[1:-1]
        
        # 4. 纯数字
        if value_expr.lstrip('-').replace('.', '', 1).isdigit():
            if '.' in value_expr:
                return float(value_expr)
            else:
                return int(value_expr)
        
        # 5. 布尔值
        if value_expr.lower() == 'true':
            return 1
        if value_expr.lower() == 'false':
            return 0
        
        # 6. 表达式
        try:
            return self.calculator.calculate(value_expr, self.variables)
        except:
            return value_expr

# ====================== 6. 主题应用器 ======================
def apply_theme(
    root: tk.Tk,
    sidebar: ttk.Treeview,
    notebook: ttk.Notebook,
    copyright_label: ttk.Label,
    theme: Dict[str, str]
) -> None:
    root.configure(bg=theme['bg'])
    
    style: ttk.Style = ttk.Style()
    tree_font: font.Font = font.Font(family=('微软雅黑', 'Consolas'), size=10)
    
    style.configure(
        'Sidebar.Treeview',
        background=theme['sidebar_bg'],
        foreground=theme['text_fg'],
        fieldbackground=theme['sidebar_bg'],
        font=tree_font
    )
    style.configure(
        'Sidebar.Treeview.Heading',
        background=theme['sidebar_bg'],
        foreground=theme['text_fg'],
        font=font.Font(family=('微软雅黑', 'Consolas'), size=10, weight='bold')
    )
    sidebar.configure(style='Sidebar.Treeview')
    
    style.configure('TNotebook', background=theme['sidebar_bg'])
    style.configure('TNotebook.Tab', background=theme['sidebar_bg'], foreground=theme['text_fg'])
    
    copyright_label.config(foreground=theme['copyright'])
    
    def set_label_color(widget: tk.Widget):
        for child in widget.winfo_children():
            if isinstance(child, (ttk.Label, ttk.Button, ttk.Frame)):
                try:
                    if isinstance(child, ttk.Label):
                        child.config(foreground=theme['text_fg'])
                    elif isinstance(child, ttk.Button):
                        child.configure(style='TButton')
                except:
                    pass
                set_label_color(child)
    
    set_label_color(root)
    
    style.configure('TButton', background=theme['sidebar_bg'], foreground=theme['text_fg'])

# ====================== 7. 标签页类 ======================
class EditorTab:
    def __init__(self, parent: ttk.Notebook, tab_id: str, title: str = "未命名", on_variable_update=None, root_window: Optional[tk.Tk] = None):
        self.tab_id = tab_id
        self.title = title
        self.file_path: Optional[str] = None
        self.interpreter: KoalaInterpreter = KoalaInterpreter(root_window)
        self.on_variable_update = on_variable_update
        self.root_window = root_window
        
        # 创建标签页框架
        self.frame = ttk.Frame(parent)
        
        # 代码编辑区
        self.code_editor = LineNumberText(self.frame, font=font.Font(family='Consolas', size=11))
        self.code_editor.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 绑定实时语法高亮
        self.code_editor.text.bind('<KeyRelease>', self.on_code_modified)
        
        # 输出区
        self.output_text = scrolledtext.ScrolledText(
            self.frame, font=font.Font(family='Consolas', size=11), 
            height=8, wrap=tk.NONE, state=tk.DISABLED
        )
        self.output_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 添加到notebook
        parent.add(self.frame, text=title)
        
        # 配置输出文本标签
        self.output_text.tag_config('success', foreground='#008000', font=('微软雅黑', 10, 'bold'))
        self.output_text.tag_config('error', foreground='#ff0000', font=('微软雅黑', 10, 'bold'))
        self.output_text.tag_config('warning', foreground='#ff9900', font=('微软雅黑', 10, 'bold'))
    
    def on_code_modified(self, event: Optional[tk.Event] = None):
        """每次按键后实时进行语法高亮"""
        highlight_syntax_realtime(self.code_editor)
    
    def execute_code(self) -> None:
        """执行当前标签页的代码"""
        code: str = self.code_editor.get('1.0', tk.END).strip()
        if not code:
            self.update_output("❌ 错误：代码编辑区为空！", 'error')
            if self.on_variable_update:
                self.on_variable_update(self.interpreter)
            return
        
        # 同步执行
        try:
            self.interpreter = KoalaInterpreter(self.root_window)
            result = self.interpreter.execute_code(code)
            self.update_output(result)
        except Exception as e:
            self.update_output(f"❌ 执行异常：{str(e)}", 'error')
    
    def update_output(self, result: str, tag: str = ''):
        """更新当前标签页的输出区域"""
        self.output_text.config(state=tk.NORMAL)
        self.output_text.delete('1.0', tk.END)
        
        if "错误" in result or "❌" in result:
            self.output_text.insert(tk.END, result, 'error')
        elif "⚠️" in result:
            self.output_text.insert(tk.END, result, 'warning')
        else:
            if result != "无输出内容":
                self.output_text.insert(tk.END, result + '\n')
            else:
                self.output_text.insert(tk.END, result)
        
        self.output_text.config(state=tk.DISABLED)
        self.output_text.see(tk.END)
        
        # 更新变量监视器
        if self.on_variable_update:
            self.on_variable_update(self.interpreter)
    
    def clear_output(self):
        """清空当前标签页的输出区域"""
        self.output_text.config(state=tk.NORMAL)
        self.output_text.delete('1.0', tk.END)
        self.output_text.config(state=tk.DISABLED)
    
    def get_code(self) -> str:
        """获取当前标签页的代码"""
        return self.code_editor.get('1.0', tk.END)
    
    def set_code(self, code: str):
        """设置当前标签页的代码"""
        self.code_editor.delete('1.0', tk.END)
        self.code_editor.insert('1.0', code)
        highlight_syntax_realtime(self.code_editor)
    
    def set_title(self, title: str):
        """设置标签页标题"""
        self.title = title
    
    def set_file_path(self, file_path: str):
        """设置标签页关联的文件路径"""
        self.file_path = file_path
        if file_path:
            self.set_title(os.path.basename(file_path))

# ====================== 8. 主界面类 ======================
class KoalaIDE(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Koala解释器 v1.0")
        self.geometry("1400x800")
        self.minsize(1000, 600)
        
        # 字体配置
        self.code_font: font.Font = font.Font(family='Consolas', size=11)
        self.label_font: font.Font = font.Font(family=('微软雅黑', 'Arial'), size=11, weight='bold')
        
        # 标签页管理
        self.notebook: ttk.Notebook
        self.tabs: Dict[str, EditorTab] = {}
        self.current_tab_id: Optional[str] = None
        self.tab_counter: int = 0
        
        # 全局布局
        self.paned_window: ttk.PanedWindow = ttk.PanedWindow(self, orient=tk.HORIZONTAL)
        self.paned_window.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 左侧文件浏览器
        self.sidebar_frame: ttk.Frame = ttk.Frame(self.paned_window, width=220)
        self.paned_window.add(self.sidebar_frame, weight=1)
        
        self.sidebar_label: ttk.Label = ttk.Label(
            self.sidebar_frame, text="      资源管理器", font=self.label_font
        )
        self.sidebar_label.pack(anchor='w', padx=10, pady=8)
        
        # 文件操作按钮
        self.btn_frame_sidebar: ttk.Frame = ttk.Frame(self.sidebar_frame)
        self.btn_frame_sidebar.pack(fill=tk.X, padx=10, pady=5)
        
        self.import_dir_btn: ttk.Button = ttk.Button(
            self.btn_frame_sidebar, text="导入目录", command=self.import_directory, width=10
        )
        self.import_dir_btn.pack(side=tk.LEFT, padx=(0, 5))
        
        self.refresh_btn: ttk.Button = ttk.Button(
            self.btn_frame_sidebar, text="刷新", command=self.refresh_directory, width=8
        )
        self.refresh_btn.pack(side=tk.LEFT)
        
        self.file_tree: ttk.Treeview = ttk.Treeview(
            self.sidebar_frame, show='tree'
        )
        self.file_tree.pack(fill=tk.BOTH, expand=True, padx=10, pady=8)
        self.file_tree.bind('<<TreeviewSelect>>', self.open_selected_file)
        
        # 变量监视器框架
        self.var_frame: ttk.Frame = ttk.Frame(self.sidebar_frame)
        self.var_frame.pack(fill=tk.X, padx=10, pady=(0, 5))
        
        self.var_label: ttk.Label = ttk.Label(
            self.var_frame, text="   系统记录与性能监视", font=self.label_font
        )
        self.var_label.pack(anchor='w')
        
        self.var_text: scrolledtext.ScrolledText = scrolledtext.ScrolledText(
            self.var_frame, height=8, font=font.Font(family='Consolas', size=9)
        )
        self.var_text.pack(fill=tk.BOTH, expand=True)
        self.var_text.config(state=tk.DISABLED)
        
        # 右侧编辑区
        self.right_frame: ttk.Frame = ttk.Frame(self.paned_window)
        self.paned_window.add(self.right_frame, weight=5)
        
        # 功能按钮
        self.btn_frame: ttk.Frame = ttk.Frame(self.right_frame)
        self.btn_frame.pack(fill=tk.X, padx=10, pady=5)
        
        self.run_btn: ttk.Button = ttk.Button(
            self.btn_frame, text="▶ 执行代码(F5)", command=self.execute_current_tab, width=12
        )
        self.run_btn.pack(side=tk.LEFT, padx=(0, 5))
        
        self.save_btn: ttk.Button = ttk.Button(
            self.btn_frame, text="💾 保存文件", command=self.save_current_tab, width=12
        )
        self.save_btn.pack(side=tk.LEFT, padx=(0, 5))
        
        self.new_tab_btn: ttk.Button = ttk.Button(
            self.btn_frame, text="📄 新建标签页", command=self.new_tab, width=15
        )
        self.new_tab_btn.pack(side=tk.LEFT, padx=(0, 5))
        
        self.theme_btn: ttk.Button = ttk.Button(
            self.btn_frame, text="🌓 隐藏按键", command=self.toggle_theme, width=10
        )
        self.theme_btn.pack(side=tk.LEFT, padx=(0, 5))
        
        self.clear_btn: ttk.Button = ttk.Button(
            self.btn_frame, text="🧹 清空输出", command=self.clear_current_output, width=10
        )
        self.clear_btn.pack(side=tk.LEFT)
        
        # 创建Notebook
        self.notebook = ttk.Notebook(self.right_frame)
        self.notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
        
        # 绑定标签页切换事件
        self.notebook.bind('<<NotebookTabChanged>>', self.on_tab_changed)
        
        # 状态栏
        self.status_bar: ttk.Frame = ttk.Frame(self.right_frame)
        self.status_bar.pack(fill=tk.X, padx=10, pady=(0, 5))
        
        self.status_label: ttk.Label = ttk.Label(
            self.status_bar, text="就绪", font=font.Font(family='微软雅黑', size=9)
        )
        self.status_label.pack(side=tk.LEFT)
        
        self.tab_info_label: ttk.Label = ttk.Label(
            self.status_bar, text="标签页: 0", font=font.Font(family='Consolas', size=9)
        )
        self.tab_info_label.pack(side=tk.RIGHT, padx=5)
        
        # 底部版权
        self.bottom_frame: ttk.Frame = ttk.Frame(self)
        self.bottom_frame.pack(fill=tk.X, side=tk.BOTTOM, anchor='se')
        
        self.copyright_label: ttk.Label = ttk.Label(
            self.bottom_frame,
            text=" Koala语言解释器 v1.0",
            font=font.Font(family='微软雅黑', size=9)
        )
        self.copyright_label.pack(side=tk.RIGHT, padx=15, pady=8)
        
        # 快捷键绑定
        self.bind('<F5>', self.execute_current_tab)
        self.bind('<Control-s>', self.save_current_tab)
        self.bind('<Control-S>', self.save_current_tab)
        self.bind('<Control-n>', self.new_tab)
        self.bind('<Control-N>', self.new_tab)
        self.bind('<Control-r>', self.refresh_directory)
        self.bind('<Control-R>', self.refresh_directory)
        self.bind('<Control-l>', self.clear_current_output)
        self.bind('<Control-L>', self.clear_current_output)
        
        # 创建初始标签页
        self.new_tab("未命名")
        
        # 初始化
        self.apply_initial_theme()
        self.after(100, self.fix_sidebar_width)
        self.update_tab_info()
        self._update_variable_monitor(None)
    
    def fix_sidebar_width(self):
        self.paned_window.sashpos(0, 250)
    
    def apply_initial_theme(self):
        current_theme: Dict[str, str] = theme_manager.get_current_theme()
        apply_theme(
            self, self.file_tree, self.notebook,
            self.copyright_label, current_theme
        )
        
        self.status_label.config(foreground=current_theme['text_fg'])
        self.tab_info_label.config(foreground=current_theme['text_fg'])
        
        self.var_text.config(
            bg=current_theme['sidebar_bg'], 
            fg=current_theme['text_fg'],
            insertbackground=current_theme['text_fg']
        )
    
    def toggle_theme(self):
        new_theme: Dict[str, str] = theme_manager.toggle_theme()
        apply_theme(
            self, self.file_tree, self.notebook,
            self.copyright_label, new_theme
        )
        self.highlight_current_tab()
        self.apply_initial_theme()
        self.status_label.config(text=f"主题已切换为{'深色' if theme_manager.is_dark_mode else '浅色'}模式")
    
    def highlight_current_tab(self):
        current_tab = self.get_current_tab()
        if current_tab:
            highlight_syntax_realtime(current_tab.code_editor)
    
    def new_tab(self, event: Optional[tk.Event] = None, title: str = "未命名"):
        self.tab_counter += 1
        tab_id = f"tab_{self.tab_counter}"
        
        tab = EditorTab(self.notebook, tab_id, title, on_variable_update=self._update_variable_monitor, root_window=self)
        self.tabs[tab_id] = tab
        
        self.notebook.select(tab.frame)
        self.current_tab_id = tab_id
        
        self.update_tab_info()
        self.status_label.config(text=f"已创建新标签页: {title}")
        
        return tab
    
    def get_current_tab(self) -> Optional[EditorTab]:
        if not self.tabs:
            return None
        
        current_tab = self.notebook.select()
        if not current_tab:
            return None
        
        tab_id = str(current_tab)
        for tab in self.tabs.values():
            if str(tab.frame) == tab_id:
                return tab
        
        return None
    
    def on_tab_changed(self, event: Optional[tk.Event] = None):
        current_tab = self.get_current_tab()
        if current_tab:
            self.current_tab_id = current_tab.tab_id
            if current_tab.file_path:
                self.status_label.config(text=f"当前文件: {os.path.basename(current_tab.file_path)}")
            else:
                self.status_label.config(text=f"当前标签页: {current_tab.title}")
            
            self._update_variable_monitor(current_tab.interpreter)
    
    def update_tab_info(self):
        tab_count = len(self.tabs)
        self.tab_info_label.config(text=f"标签页: {tab_count}")
    
    def execute_current_tab(self, event: Optional[tk.Event] = None):
        current_tab = self.get_current_tab()
        if current_tab:
            current_tab.execute_code()
            self.status_label.config(text="执行完成")
    
    def save_current_tab(self, event: Optional[tk.Event] = None):
        current_tab = self.get_current_tab()
        if not current_tab:
            return
        
        content: str = current_tab.get_code()
        if not content.strip():
            messagebox.showinfo("提示", "无内容可保存")
            return
        
        if not current_tab.file_path:
            current_tab.file_path = filedialog.asksaveasfilename(
                title="保存Koala文件",
                defaultextension=".ko",
                filetypes=[("Koala语言文件", "*.ko"), ("所有文件", "*.*")]
            )
            if not current_tab.file_path:
                return
        
        try:
            with open(current_tab.file_path, 'w', encoding='utf-8') as f:
                f.write(content)
            
            current_tab.set_file_path(current_tab.file_path)
            
            tab_index = self.notebook.index(current_tab.frame)
            self.notebook.tab(tab_index, text=os.path.basename(current_tab.file_path))
            
            self.status_label.config(text=f"已保存: {os.path.basename(current_tab.file_path)}")
            
            self.refresh_directory()
        except Exception as e:
            messagebox.showerror("保存失败", f"无法保存文件：{str(e)}")
    
    def clear_current_output(self, event: Optional[tk.Event] = None):
        current_tab = self.get_current_tab()
        if current_tab:
            current_tab.clear_output()
            self.status_label.config(text="输出已清空")
    
    def import_directory(self):
        dir_path: str = filedialog.askdirectory(title="选择要导入的目录")
        if not dir_path:
            return
        for item in self.file_tree.get_children():
            self.file_tree.delete(item)
        self.load_directory_to_tree(dir_path, '')
        self.status_label.config(text=f"已导入目录: {os.path.basename(dir_path)}")
    
    def refresh_directory(self, event: Optional[tk.Event] = None):
        if not self.file_tree.get_children():
            return
        
        root_items = self.file_tree.get_children()
        if root_items:
            first_item = root_items[0]
            item_path = self.file_tree.item(first_item, 'values')
            if item_path and item_path[0]:
                dir_path = os.path.dirname(item_path[0])
            else:
                dir_path = self._find_directory_path(first_item)
        else:
            dir_path = None
        
        if dir_path and os.path.isdir(dir_path):
            for item in self.file_tree.get_children():
                self.file_tree.delete(item)
            self.load_directory_to_tree(dir_path, '')
            self.status_label.config(text=f"目录已刷新: {os.path.basename(dir_path)}")
    
    def _find_directory_path(self, item: str) -> Optional[str]:
        values = self.file_tree.item(item, 'values')
        if values and values[0]:
            return os.path.dirname(values[0])
        
        parent = self.file_tree.parent(item)
        if parent:
            return self._find_directory_path(parent)
        
        return None
    
    def load_directory_to_tree(self, dir_path: str, parent: str):
        try:
            for item in sorted(os.listdir(dir_path)):
                item_path: str = os.path.join(dir_path, item)
                if os.path.isdir(item_path):
                    node: str = self.file_tree.insert(parent, tk.END, text=item, 
                                                      values=(item_path,), open=False)
                    try:
                        sub_items = os.listdir(item_path)[:10]
                        for sub_item in sub_items:
                            sub_path = os.path.join(item_path, sub_item)
                            if os.path.isdir(sub_path):
                                self.file_tree.insert(node, tk.END, text=sub_item, 
                                                     values=(sub_path,), open=False)
                            elif sub_item.endswith('.ko'):
                                self.file_tree.insert(node, tk.END, text=sub_item, 
                                                     values=(sub_path,))
                    except (PermissionError, OSError):
                        pass
                elif item.endswith('.ko'):
                    self.file_tree.insert(parent, tk.END, text=item, values=(item_path,))
        except PermissionError:
            messagebox.showwarning("权限不足", "无法访问该目录，已跳过")
        except Exception as e:
            messagebox.showerror("加载失败", f"目录加载错误：{str(e)}")
    
    def open_selected_file(self, event: tk.Event):
        selected_items = self.file_tree.selection()
        if not selected_items:
            return
        
        item: str = selected_items[0]
        values: Tuple[str] = self.file_tree.item(item, 'values')
        if not values:
            return
        
        file_path: str = values[0]
        if not file_path.endswith('.ko'):
            return
        
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content: str = f.read()
            
            for tab in self.tabs.values():
                if tab.file_path == file_path:
                    self.notebook.select(tab.frame)
                    self.status_label.config(text=f"已切换到: {os.path.basename(file_path)}")
                    return
            
            tab = self.new_tab(title=os.path.basename(file_path))
            tab.set_code(content)
            tab.set_file_path(file_path)
            
            tab_index = self.notebook.index(tab.frame)
            self.notebook.tab(tab_index, text=os.path.basename(file_path))
            
            self.status_label.config(text=f"已打开: {os.path.basename(file_path)}")
        except Exception as e:
            messagebox.showerror("打开失败", f"无法打开文件：{str(e)}")
    
    def _update_variable_monitor(self, interpreter: Optional[KoalaInterpreter]):
        self.var_text.config(state=tk.NORMAL)
        self.var_text.delete('1.0', tk.END)
        
        if interpreter is None:
            self.var_text.insert(tk.END, "无变量数据")
        else:
            if interpreter.variables:
                self.var_text.insert(tk.END, "📦 变量:\n")
                for var_name, value in interpreter.variables.items():
                    if isinstance(value, list):
                        display_value = str(value)
                        if len(display_value) > 50:
                            display_value = display_value[:50] + "..."
                        self.var_text.insert(tk.END, f"  {var_name}: 数组[{len(value)}] = {display_value}\n")
                    else:
                        self.var_text.insert(tk.END, f"  {var_name} = {repr(value)}\n")
                self.var_text.insert(tk.END, "\n")
            
            if interpreter.classes:
                self.var_text.insert(tk.END, "🏗️ 类定义:\n")
                for class_name, class_data in interpreter.classes.items():
                    self.var_text.insert(tk.END, f"  {class_name}\n")
                self.var_text.insert(tk.END, "\n")
            
            if interpreter.instances:
                self.var_text.insert(tk.END, "🔧 实例:\n")
                for inst_name, inst_data in interpreter.instances.items():
                    self.var_text.insert(tk.END, f"  {inst_name}: {inst_data['class']}\n")
                    for attr_name, attr_value in inst_data['attrs'].items():
                        self.var_text.insert(tk.END, f"    .{attr_name} = {repr(attr_value)}\n")
                self.var_text.insert(tk.END, "\n")
            
            if hasattr(interpreter, 'execution_stats') and interpreter.execution_stats.get('total_lines', 0) > 0:
                stats = interpreter.execution_stats
                self.var_text.insert(tk.END, "📊 执行统计:\n")
                self.var_text.insert(tk.END, f"  总行数: {stats.get('total_lines', 0)}\n")
                self.var_text.insert(tk.END, f"  执行行数: {stats.get('executed_lines', 0)}\n")
                self.var_text.insert(tk.END, f"  创建变量: {stats.get('variables_created', 0)}\n")
                self.var_text.insert(tk.END, f"  创建数组: {stats.get('arrays_created', 0)}\n")
                self.var_text.insert(tk.END, f"  创建实例: {stats.get('instances_created', 0)}\n")
                if stats.get('start_time', 0) > 0 and stats.get('end_time', 0) > 0:
                    execution_time = stats['end_time'] - stats['start_time']
                    self.var_text.insert(tk.END, f"  执行时间: {execution_time:.3f}秒\n")
            
            if not interpreter.variables and not interpreter.classes and not interpreter.instances:
                self.var_text.insert(tk.END, "暂无变量数据")
        
        self.var_text.config(state=tk.DISABLED)
        self.var_text.see(tk.END)

# ====================== 程序入口 ======================
if __name__ == '__main__':
    app: KoalaIDE = KoalaIDE()
    app.mainloop()