import tkinter as tk
from tkinter import ttk, messagebox
import math
import re
from datetime import datetime

class AICalculator:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("🤖 AI Calculator")
        self.window.geometry("400x600")
        self.window.configure(bg="#1a1a2e")
        
        # 设置样式
        self.setup_styles()
        
        # 初始化变量
        self.current_input = ""
        self.result = ""
        self.history = []
        self.memory = 0
        
        # 创建界面
        self.create_widgets()
        
    def setup_styles(self):
        """设置界面样式"""
        self.style = ttk.Style()
        self.style.theme_use('clam')
        
        # 配置按钮样式
        self.style.configure('Number.TButton', 
                           background='#16213e',
                           foreground='white',
                           font=('Arial', 14),
                           borderwidth=0)
        self.style.map('Number.TButton',
                      background=[('active', '#0f3460')])
        
        self.style.configure('Operator.TButton',
                           background='#e94560',
                           foreground='white',
                           font=('Arial', 14, 'bold'),
                           borderwidth=0)
        self.style.map('Operator.TButton',
                      background=[('active', '#ff6b81')])
        
        self.style.configure('Function.TButton',
                           background='#1e96fc',
                           foreground='white',
                           font=('Arial', 12),
                           borderwidth=0)
        self.style.map('Function.TButton',
                      background=[('active', '#4da0ff')])
        
        self.style.configure('Memory.TButton',
                           background='#00c9a7',
                           foreground='white',
                           font=('Arial', 12),
                           borderwidth=0)
        self.style.map('Memory.TButton',
                      background=[('active', '#33d9b2')])
        
        self.style.configure('Clear.TButton',
                           background='#ff9f1c',
                           foreground='white',
                           font=('Arial', 12, 'bold'),
                           borderwidth=0)
        self.style.map('Clear.TButton',
                      background=[('active', '#ffaa33')])
    
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = tk.Frame(self.window, bg="#1a1a2e")
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 标题
        title_label = tk.Label(main_frame, 
                              text="🤖 AI Calculator",
                              font=("Arial", 18, "bold"),
                              fg="#e94560",
                              bg="#1a1a2e")
        title_label.pack(pady=(0, 10))
        
        # 显示屏框架
        display_frame = tk.Frame(main_frame, bg="#0f3460", relief="raised", bd=2)
        display_frame.pack(fill=tk.X, pady=(0, 10))
        
        # 输入显示
        self.input_var = tk.StringVar()
        input_display = tk.Label(display_frame,
                                textvariable=self.input_var,
                                font=("Arial", 12),
                                fg="lightgray",
                                bg="#0f3460",
                                anchor="e",
                                padx=10,
                                pady=5)
        input_display.pack(fill=tk.X)
        
        # 结果显示
        self.result_var = tk.StringVar(value="0")
        result_display = tk.Label(display_frame,
                                 textvariable=self.result_var,
                                 font=("Arial", 20, "bold"),
                                 fg="white",
                                 bg="#0f3460",
                                 anchor="e",
                                 padx=10,
                                 pady=10)
        result_display.pack(fill=tk.X)
        
        # 功能按钮区域
        func_frame = tk.Frame(main_frame, bg="#1a1a2e")
        func_frame.pack(fill=tk.X, pady=(0, 10))
        
        # 内存功能按钮
        ttk.Button(func_frame, text="MC", style='Memory.TButton', 
                  command=self.memory_clear).pack(side=tk.LEFT, padx=2, fill=tk.X, expand=True)
        ttk.Button(func_frame, text="MR", style='Memory.TButton', 
                  command=self.memory_recall).pack(side=tk.LEFT, padx=2, fill=tk.X, expand=True)
        ttk.Button(func_frame, text="M+", style='Memory.TButton', 
                  command=self.memory_add).pack(side=tk.LEFT, padx=2, fill=tk.X, expand=True)
        ttk.Button(func_frame, text="M-", style='Memory.TButton', 
                  command=self.memory_subtract).pack(side=tk.LEFT, padx=2, fill=tk.X, expand=True)
        
        # 高级函数按钮
        advanced_frame = tk.Frame(main_frame, bg="#1a1a2e")
        advanced_frame.pack(fill=tk.X, pady=(0, 10))
        
        functions = [
            ("sin", self.sin_func), ("cos", self.cos_func), ("tan", self.tan_func),
            ("√", self.sqrt_func), ("x²", self.square_func), ("1/x", self.inverse_func),
            ("log", self.log_func), ("ln", self.ln_func), ("π", self.pi_func)
        ]
        
        for i, (text, command) in enumerate(functions):
            row = i // 3
            col = i % 3
            btn_frame = tk.Frame(advanced_frame, bg="#1a1a2e")
            btn_frame.grid(row=row, column=col, padx=2, pady=2, sticky="nsew")
            
            ttk.Button(btn_frame, text=text, style='Function.TButton',
                      command=command).pack(fill=tk.BOTH, expand=True)
        
        advanced_frame.columnconfigure((0, 1, 2), weight=1)
        
        # 数字和操作符按钮
        button_frame = tk.Frame(main_frame, bg="#1a1a2e")
        button_frame.pack(fill=tk.BOTH, expand=True)
        
        # 按钮布局
        buttons = [
            ['C', '±', '%', '÷'],
            ['7', '8', '9', '×'],
            ['4', '5', '6', '-'],
            ['1', '2', '3', '+'],
            ['0', '.', '=', '⌫']
        ]
        
        for i, row in enumerate(buttons):
            button_frame.rowconfigure(i, weight=1)
            for j, text in enumerate(row):
                button_frame.columnconfigure(j, weight=1)
                
                if text in '0123456789':
                    style = 'Number.TButton'
                    command = lambda x=text: self.button_click(x)
                elif text in '÷×-+':
                    style = 'Operator.TButton'
                    command = lambda x=text: self.operator_click(x)
                elif text == '=':
                    style = 'Operator.TButton'
                    command = self.calculate
                elif text == 'C':
                    style = 'Clear.TButton'
                    command = self.clear_all
                elif text == '⌫':
                    style = 'Clear.TButton'
                    command = self.backspace
                elif text == '±':
                    style = 'Number.TButton'
                    command = self.toggle_sign
                elif text == '%':
                    style = 'Number.TButton'
                    command = self.percentage
                else:
                    style = 'Number.TButton'
                    command = lambda x=text: self.button_click(x)
                
                btn = ttk.Button(button_frame, text=text, style=style, command=command)
                btn.grid(row=i, column=j, sticky="nsew", padx=2, pady=2)
        
        # 历史记录按钮
        history_btn = ttk.Button(main_frame, text="📜 View History", 
                                style='Function.TButton', command=self.show_history)
        history_btn.pack(pady=(10, 0), fill=tk.X)
    
    def button_click(self, value):
        """处理数字和小数点按钮点击"""
        if value == '.' and '.' in self.current_input:
            return
        
        self.current_input += value
        self.input_var.set(self.current_input)
    
    def operator_click(self, operator):
        """处理操作符按钮点击"""
        # 将操作符转换为Python可识别的符号
        op_map = {'÷': '/', '×': '*'}
        python_op = op_map.get(operator, operator)
        
        if self.current_input:
            self.current_input += python_op
        elif self.result:
            self.current_input = self.result + python_op
        
        self.input_var.set(self.current_input)
    
    def calculate(self):
        """执行计算"""
        try:
            if not self.current_input:
                return
            
            # 安全计算表达式
            result = self.safe_eval(self.current_input)
            
            # 格式化结果
            if isinstance(result, float) and result.is_integer():
                result = int(result)
            elif isinstance(result, float):
                result = round(result, 10)  # 避免浮点精度问题
            
            self.result = str(result)
            self.result_var.set(self.result)
            
            # 添加到历史记录
            timestamp = datetime.now().strftime("%H:%M:%S")
            self.history.append(f"[{timestamp}] {self.current_input} = {self.result}")
            
            self.current_input = ""
            self.input_var.set("")
            
        except Exception as e:
            messagebox.showerror("Error", "Invalid expression!")
            self.clear_all()
    
    def safe_eval(self, expression):
        """安全地计算数学表达式"""
        # 移除所有空白字符
        expression = expression.replace(' ', '')
        
        # 只允许特定的字符
        allowed_chars = set('0123456789+-*/.()')
        if not all(c in allowed_chars or c in 'math.' for c in expression):
            raise ValueError("Invalid characters in expression")
        
        # 使用eval，但限制可用的命名空间
        safe_dict = {
            "__builtins__": {},
            "math": math,
            "abs": abs,
            "round": round,
            "int": int,
            "float": float
        }
        
        return eval(expression, safe_dict)
    
    def clear_all(self):
        """清除所有输入"""
        self.current_input = ""
        self.result = "0"
        self.input_var.set("")
        self.result_var.set("0")
    
    def backspace(self):
        """删除最后一个字符"""
        if self.current_input:
            self.current_input = self.current_input[:-1]
            self.input_var.set(self.current_input)
    
    def toggle_sign(self):
        """切换正负号"""
        if self.current_input:
            if self.current_input.startswith('-'):
                self.current_input = self.current_input[1:]
            else:
                self.current_input = '-' + self.current_input
            self.input_var.set(self.current_input)
        elif self.result and self.result != "0":
            if self.result.startswith('-'):
                self.result = self.result[1:]
            else:
                self.result = '-' + self.result
            self.result_var.set(self.result)
    
    def percentage(self):
        """百分比计算"""
        try:
            if self.current_input:
                value = float(self.current_input)
                self.current_input = str(value / 100)
                self.input_var.set(self.current_input)
            elif self.result:
                value = float(self.result)
                self.result = str(value / 100)
                self.result_var.set(self.result)
        except:
            messagebox.showerror("Error", "Invalid input for percentage!")
    
    # 高级函数
    def sin_func(self):
        self.unary_function(math.sin, "sin")
    
    def cos_func(self):
        self.unary_function(math.cos, "cos")
    
    def tan_func(self):
        self.unary_function(math.tan, "tan")
    
    def sqrt_func(self):
        self.unary_function(math.sqrt, "√")
    
    def square_func(self):
        if self.current_input:
            try:
                value = float(self.current_input)
                result = value ** 2
                self.current_input = str(result)
                self.input_var.set(self.current_input)
            except:
                messagebox.showerror("Error", "Invalid input!")
        elif self.result:
            try:
                value = float(self.result)
                self.result = str(value ** 2)
                self.result_var.set(self.result)
            except:
                messagebox.showerror("Error", "Invalid input!")
    
    def inverse_func(self):
        self.unary_function(lambda x: 1/x, "1/")
    
    def log_func(self):
        self.unary_function(math.log10, "log")
    
    def ln_func(self):
        self.unary_function(math.log, "ln")
    
    def pi_func(self):
        pi_str = str(math.pi)
        if self.current_input:
            self.current_input += pi_str
        else:
            self.current_input = pi_str
        self.input_var.set(self.current_input)
    
    def unary_function(self, func, func_name):
        """处理一元函数"""
        try:
            if self.current_input:
                value = float(self.current_input)
                result = func(value)
                self.current_input = str(result)
                self.input_var.set(self.current_input)
            elif self.result:
                value = float(self.result)
                self.result = str(func(value))
                self.result_var.set(self.result)
        except:
            messagebox.showerror("Error", f"Invalid input for {func_name}!")
    
    # 内存功能
    def memory_clear(self):
        self.memory = 0
    
    def memory_recall(self):
        self.current_input = str(self.memory)
        self.input_var.set(self.current_input)
    
    def memory_add(self):
        try:
            if self.current_input:
                self.memory += float(self.current_input)
            elif self.result:
                self.memory += float(self.result)
        except:
            pass
    
    def memory_subtract(self):
        try:
            if self.current_input:
                self.memory -= float(self.current_input)
            elif self.result:
                self.memory -= float(self.result)
        except:
            pass
    
    def show_history(self):
        """显示计算历史"""
        if not self.history:
            messagebox.showinfo("History", "No calculation history yet!")
            return
        
        history_window = tk.Toplevel(self.window)
        history_window.title("Calculation History")
        history_window.geometry("400x300")
        history_window.configure(bg="#1a1a2e")
        
        # 创建文本框
        text_widget = tk.Text(history_window, bg="#0f3460", fg="white", 
                             font=("Arial", 10), wrap=tk.WORD)
        text_widget.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 插入历史记录
        for record in reversed(self.history[-20:]):  # 显示最近20条记录
            text_widget.insert(tk.END, record + "\n")
        
        text_widget.config(state=tk.DISABLED)
    
    def run(self):
        """运行计算器"""
        self.window.mainloop()

# 运行计算器
if __name__ == "__main__":
    calculator = AICalculator()
    calculator.run()