import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox, filedialog, font
import threading
import time
import json
import os
import pyperclip
from datetime import datetime
from googletrans import Translator, LANGUAGES
import requests
from urllib.parse import quote
import hashlib
import random
import logging
from PIL import Image, ImageTk
import pyttsx3
import pygame
import queue
from concurrent.futures import ThreadPoolExecutor
import html
import re

# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# 初始化pygame mixer用于音频播放
pygame.mixer.init()

class TranslationApp:
    def __init__(self, root):
        self.root = root
        self.root.title("智能翻译助手 v2.0")
        self.root.geometry("1200x700")
        
        # 设置应用图标
        self.setup_icon()
        
        # 颜色方案
        self.colors = {
            'primary': '#2c3e50',
            'secondary': '#3498db',
            'accent': '#e74c3c',
            'success': '#2ecc71',
            'warning': '#f39c12',
            'light': '#ecf0f1',
            'dark': '#34495e',
            'text': '#2c3e50',
            'bg': '#f5f7fa'
        }
        
        # 配置设置
        self.config = {
            'auto_translate': True,
            'auto_copy': False,
            'auto_play_sound': False,
            'show_pronunciation': True,
            'translation_engine': 'google',
            'theme': 'light',
            'font_size': 12,
            'save_history': True,
            'max_history': 1000
        }
        
        # 加载配置
        self.load_config()
        
        # 初始化翻译器
        self.translators = {
            'google': Translator(),
            'baidu': None,  # 百度翻译需要API
            'youdao': None  # 有道翻译需要API
        }
        
        # 初始化语音引擎
        self.tts_engine = None
        self.init_tts_engine()
        
        # 语言列表
        self.languages = list(LANGUAGES.items())
        self.languages.sort(key=lambda x: x[1])
        
        # 翻译历史
        self.translation_history = []
        self.load_history()
        
        # 常用语言
        self.common_languages = [
            ('en', '英语'),
            ('zh-CN', '中文(简体)'),
            ('ja', '日语'),
            ('ko', '韩语'),
            ('fr', '法语'),
            ('de', '德语'),
            ('es', '西班牙语'),
            ('ru', '俄语'),
            ('ar', '阿拉伯语'),
            ('pt', '葡萄牙语')
        ]
        
        # 创建UI
        self.setup_ui()
        
        # 初始化队列
        self.translation_queue = queue.Queue()
        
        # 启动翻译线程
        self.running = True
        self.translation_thread = threading.Thread(target=self.process_translation_queue, daemon=True)
        self.translation_thread.start()
        
        # 绑定事件
        self.bind_events()
        
    def setup_icon(self):
        """设置应用图标"""
        try:
            # 尝试加载图标文件
            icon_path = "translation_icon.ico"
            if os.path.exists(icon_path):
                self.root.iconbitmap(icon_path)
        except:
            pass
            
    def init_tts_engine(self):
        """初始化语音引擎"""
        try:
            self.tts_engine = pyttsx3.init()
            # 设置语音属性
            voices = self.tts_engine.getProperty('voices')
            if voices:
                # 尝试找到中文语音
                for voice in voices:
                    if 'chinese' in voice.name.lower() or 'zh' in voice.id.lower():
                        self.tts_engine.setProperty('voice', voice.id)
                        break
        except Exception as e:
            logger.error(f"初始化TTS引擎失败: {e}")
            self.tts_engine = None
            
    def setup_ui(self):
        """设置用户界面"""
        # 主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 创建菜单
        self.setup_menu()
        
        # 顶部工具栏
        self.setup_toolbar(main_frame)
        
        # 翻译区域
        self.setup_translation_area(main_frame)
        
        # 历史记录区域
        self.setup_history_area(main_frame)
        
        # 状态栏
        self.setup_statusbar()
        
    def setup_menu(self):
        """设置菜单栏"""
        menubar = tk.Menu(self.root)
        self.root.config(menu=menubar)
        
        # 文件菜单
        file_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="文件", menu=file_menu)
        file_menu.add_command(label="打开文件...", command=self.open_file)
        file_menu.add_command(label="保存翻译...", command=self.save_translation)
        file_menu.add_separator()
        file_menu.add_command(label="导出历史...", command=self.export_history)
        file_menu.add_command(label="导入历史...", command=self.import_history)
        file_menu.add_separator()
        file_menu.add_command(label="退出", command=self.root.quit)
        
        # 编辑菜单
        edit_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="编辑", menu=edit_menu)
        edit_menu.add_command(label="复制原文", command=lambda: self.copy_text('source'))
        edit_menu.add_command(label="复制译文", command=lambda: self.copy_text('target'))
        edit_menu.add_separator()
        edit_menu.add_command(label="清空输入", command=self.clear_input)
        edit_menu.add_command(label="清空历史", command=self.clear_history)
        
        # 工具菜单
        tools_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="工具", menu=tools_menu)
        tools_menu.add_command(label="设置", command=self.open_settings)
        tools_menu.add_command(label="语言检测", command=self.detect_language)
        tools_menu.add_command(label="文字转语音", command=self.text_to_speech)
        
        # 帮助菜单
        help_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="帮助", menu=help_menu)
        help_menu.add_command(label="使用说明", command=self.show_help)
        help_menu.add_command(label="关于", command=self.show_about)
        
    def setup_toolbar(self, parent):
        """设置工具栏"""
        toolbar = ttk.Frame(parent)
        toolbar.pack(fill=tk.X, pady=(0, 10))
        
        # 翻译引擎选择
        ttk.Label(toolbar, text="引擎:").pack(side=tk.LEFT, padx=(0, 5))
        self.engine_var = tk.StringVar(value=self.config['translation_engine'])
        engine_combo = ttk.Combobox(toolbar, textvariable=self.engine_var, 
                                   values=['google', 'baidu', 'youdao'], 
                                   width=10, state='readonly')
        engine_combo.pack(side=tk.LEFT, padx=(0, 10))
        engine_combo.bind('<<ComboboxSelected>>', self.on_engine_change)
        
        # 源语言选择
        ttk.Label(toolbar, text="从:").pack(side=tk.LEFT, padx=(0, 5))
        self.source_lang_var = tk.StringVar(value='auto')
        source_combo = ttk.Combobox(toolbar, textvariable=self.source_lang_var, 
                                   values=['auto'] + [code for code, _ in self.common_languages], 
                                   width=15, state='readonly')
        source_combo.pack(side=tk.LEFT, padx=(0, 10))
        
        # 交换按钮
        swap_btn = ttk.Button(toolbar, text="⇄", width=3, command=self.swap_languages)
        swap_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        # 目标语言选择
        ttk.Label(toolbar, text="到:").pack(side=tk.LEFT, padx=(0, 5))
        self.target_lang_var = tk.StringVar(value='zh-CN')
        target_combo = ttk.Combobox(toolbar, textvariable=self.target_lang_var, 
                                   values=[code for code, _ in self.common_languages], 
                                   width=15, state='readonly')
        target_combo.pack(side=tk.LEFT, padx=(0, 10))
        
        # 自动翻译开关
        self.auto_translate_var = tk.BooleanVar(value=self.config['auto_translate'])
        auto_check = ttk.Checkbutton(toolbar, text="自动翻译", 
                                    variable=self.auto_translate_var)
        auto_check.pack(side=tk.LEFT, padx=(0, 10))
        
        # 翻译按钮
        translate_btn = ttk.Button(toolbar, text="翻译", command=self.manual_translate)
        translate_btn.pack(side=tk.LEFT)
        
    def setup_translation_area(self, parent):
        """设置翻译区域"""
        trans_frame = ttk.Frame(parent)
        trans_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
        
        # 源文本区域
        source_frame = ttk.LabelFrame(trans_frame, text="原文", padding=5)
        source_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5))
        
        # 原文输入区域
        self.source_text = scrolledtext.ScrolledText(
            source_frame, wrap=tk.WORD, height=15,
            font=('Microsoft YaHei', self.config['font_size'])
        )
        self.source_text.pack(fill=tk.BOTH, expand=True)
        
        # 源文本工具栏
        source_toolbar = ttk.Frame(source_frame)
        source_toolbar.pack(fill=tk.X, pady=(5, 0))
        
        ttk.Button(source_toolbar, text="粘贴", command=self.paste_to_source).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(source_toolbar, text="清空", command=self.clear_source).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(source_toolbar, text="朗读", command=lambda: self.play_sound('source')).pack(side=tk.LEFT)
        
        # 目标文本区域
        target_frame = ttk.LabelFrame(trans_frame, text="译文", padding=5)
        target_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(5, 0))
        
        # 译文显示区域
        self.target_text = scrolledtext.ScrolledText(
            target_frame, wrap=tk.WORD, height=15,
            font=('Microsoft YaHei', self.config['font_size']), state='normal'
        )
        self.target_text.pack(fill=tk.BOTH, expand=True)
        
        # 目标文本工具栏
        target_toolbar = ttk.Frame(target_frame)
        target_toolbar.pack(fill=tk.X, pady=(5, 0))
        
        ttk.Button(target_toolbar, text="复制", command=self.copy_translation).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(target_toolbar, text="朗读", command=lambda: self.play_sound('target')).pack(side=tk.LEFT)
        
        # 发音和音标显示
        if self.config['show_pronunciation']:
            self.setup_pronunciation_area(target_frame)
            
    def setup_pronunciation_area(self, parent):
        """设置发音显示区域"""
        pron_frame = ttk.Frame(parent)
        pron_frame.pack(fill=tk.X, pady=(5, 0))
        
        ttk.Label(pron_frame, text="发音:").pack(side=tk.LEFT)
        self.pronunciation_var = tk.StringVar()
        pron_label = ttk.Label(pron_frame, textvariable=self.pronunciation_var, foreground='blue')
        pron_label.pack(side=tk.LEFT, padx=(5, 0))
        
    def setup_history_area(self, parent):
        """设置历史记录区域"""
        history_frame = ttk.LabelFrame(parent, text="翻译历史", padding=5)
        history_frame.pack(fill=tk.BOTH, expand=False, pady=(0, 10))
        
        # 创建Treeview显示历史
        columns = ('time', 'source', 'target', 'from_lang', 'to_lang')
        self.history_tree = ttk.Treeview(history_frame, columns=columns, show='headings', height=6)
        
        # 设置列
        self.history_tree.heading('time', text='时间')
        self.history_tree.heading('source', text='原文')
        self.history_tree.heading('target', text='译文')
        self.history_tree.heading('from_lang', text='源语言')
        self.history_tree.heading('to_lang', text='目标语言')
        
        # 设置列宽
        self.history_tree.column('time', width=120)
        self.history_tree.column('source', width=200)
        self.history_tree.column('target', width=200)
        self.history_tree.column('from_lang', width=80)
        self.history_tree.column('to_lang', width=80)
        
        # 滚动条
        scrollbar = ttk.Scrollbar(history_frame, orient=tk.VERTICAL, command=self.history_tree.yview)
        self.history_tree.configure(yscrollcommand=scrollbar.set)
        
        # 布局
        self.history_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 绑定双击事件
        self.history_tree.bind('<Double-Button-1>', self.on_history_double_click)
        
        # 历史操作工具栏
        history_toolbar = ttk.Frame(history_frame)
        history_toolbar.pack(fill=tk.X, pady=(5, 0))
        
        ttk.Button(history_toolbar, text="使用原文", command=self.use_history_source).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(history_toolbar, text="使用译文", command=self.use_history_target).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(history_toolbar, text="删除", command=self.delete_history_item).pack(side=tk.LEFT)
        
    def setup_statusbar(self):
        """设置状态栏"""
        self.status_var = tk.StringVar(value="就绪")
        statusbar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        statusbar.pack(side=tk.BOTTOM, fill=tk.X)
        
    def bind_events(self):
        """绑定事件"""
        # 绑定文本变化事件
        self.source_text.bind('<KeyRelease>', self.on_source_text_change)
        
        # 绑定快捷键
        self.root.bind('<Control-t>', lambda e: self.manual_translate())
        self.root.bind('<Control-s>', lambda e: self.save_translation())
        self.root.bind('<Control-o>', lambda e: self.open_file())
        self.root.bind('<Control-c>', lambda e: self.copy_translation())
        self.root.bind('<Control-v>', lambda e: self.paste_to_source())
        self.root.bind('<Control-l>', lambda e: self.clear_input())
        self.root.bind('<F1>', lambda e: self.show_help())
        
    def on_source_text_change(self, event=None):
        """源文本变化事件"""
        if self.auto_translate_var.get():
            # 延迟翻译，避免频繁请求
            if hasattr(self, 'translation_timer'):
                self.root.after_cancel(self.translation_timer)
            self.translation_timer = self.root.after(500, self.manual_translate)  # 500ms后翻译
            
    def on_engine_change(self, event=None):
        """引擎改变事件"""
        self.config['translation_engine'] = self.engine_var.get()
        self.save_config()
        
    def swap_languages(self):
        """交换源语言和目标语言"""
        source = self.source_lang_var.get()
        target = self.target_lang_var.get()
        
        # 如果源语言是auto，不交换
        if source == 'auto':
            return
            
        self.source_lang_var.set(target)
        self.target_lang_var.set(source)
        
        # 如果有文本，交换并翻译
        source_text = self.source_text.get('1.0', tk.END).strip()
        target_text = self.target_text.get('1.0', tk.END).strip()
        
        if source_text and target_text:
            self.source_text.delete('1.0', tk.END)
            self.source_text.insert('1.0', target_text)
            self.manual_translate()
            
    def manual_translate(self):
        """手动翻译"""
        text = self.source_text.get('1.0', tk.END).strip()
        if not text:
            return
            
        # 添加到翻译队列
        self.translation_queue.put({
            'text': text,
            'src': self.source_lang_var.get(),
            'dest': self.target_lang_var.get(),
            'engine': self.engine_var.get()
        })
        
    def process_translation_queue(self):
        """处理翻译队列"""
        while self.running:
            try:
                task = self.translation_queue.get(timeout=1)
                if task:
                    self.perform_translation(task)
            except queue.Empty:
                continue
            except Exception as e:
                logger.error(f"翻译处理错误: {e}")
                
    def perform_translation(self, task):
        """执行翻译"""
        try:
            self.status_var.set("翻译中...")
            
            text = task['text']
            src = task['src']
            dest = task['dest']
            engine = task['engine']
            
            if engine == 'google':
                result = self.google_translate(text, src, dest)
            elif engine == 'baidu':
                result = self.baidu_translate(text, src, dest)
            elif engine == 'youdao':
                result = self.youdao_translate(text, src, dest)
            else:
                result = {'translated': '不支持的翻译引擎', 'src': src, 'dest': dest}
                
            # 更新UI
            self.root.after(0, self.update_translation_result, result)
            
            # 添加到历史记录
            if result.get('translated'):
                self.add_to_history(text, result['translated'], result.get('src', src), result.get('dest', dest))
                
        except Exception as e:
            logger.error(f"翻译失败: {e}")
            error_result = {
                'translated': f"翻译失败: {str(e)}",
                'src': task.get('src', ''),
                'dest': task.get('dest', '')
            }
            self.root.after(0, self.update_translation_result, error_result)
        finally:
            self.root.after(0, lambda: self.status_var.set("就绪"))
            
    def google_translate(self, text, src, dest):
        """Google翻译"""
        translator = self.translators['google']
        result = translator.translate(text, src=src, dest=dest)
        
        return {
            'translated': result.text,
            'src': result.src,
            'dest': dest,
            'pronunciation': getattr(result, 'pronunciation', '')
        }
        
    def baidu_translate(self, text, src, dest):
        """百度翻译（需要API）"""
        # 这里需要设置百度API
        appid = ''  # 你的百度API ID
        secret_key = ''  # 你的百度密钥
        
        if not appid or not secret_key:
            return {'translated': '请设置百度翻译API', 'src': src, 'dest': dest}
            
        # 百度翻译API实现
        url = "http://api.fanyi.baidu.com/api/trans/vip/translate"
        
        # 生成签名
        salt = random.randint(32768, 65536)
        sign = appid + text + str(salt) + secret_key
        sign = hashlib.md5(sign.encode()).hexdigest()
        
        params = {
            'q': text,
            'from': src if src != 'auto' else 'auto',
            'to': dest,
            'appid': appid,
            'salt': salt,
            'sign': sign
        }
        
        response = requests.get(url, params=params)
        result = response.json()
        
        if 'trans_result' in result:
            translated = '\n'.join([item['dst'] for item in result['trans_result']])
            return {'translated': translated, 'src': src, 'dest': dest}
        else:
            return {'translated': f"百度翻译错误: {result.get('error_msg', '未知错误')}", 'src': src, 'dest': dest}
            
    def youdao_translate(self, text, src, dest):
        """有道翻译（需要API）"""
        # 这里需要设置有道API
        app_key = ''  # 你的有道API Key
        secret_key = ''  # 你的有道密钥
        
        if not app_key or not secret_key:
            return {'translated': '请设置有道翻译API', 'src': src, 'dest': dest}
            
        # 有道翻译API实现
        url = "https://openapi.youdao.com/api"
        
        # 生成签名
        salt = str(random.randint(1, 65536))
        sign_str = app_key + text + salt + secret_key
        sign = hashlib.md5(sign_str.encode()).hexdigest()
        
        params = {
            'q': text,
            'from': src if src != 'auto' else 'auto',
            'to': dest,
            'appKey': app_key,
            'salt': salt,
            'sign': sign
        }
        
        response = requests.get(url, params=params)
        result = response.json()
        
        if result.get('errorCode') == '0':
            return {'translated': result.get('translation', [''])[0], 'src': src, 'dest': dest}
        else:
            return {'translated': f"有道翻译错误: {result.get('errorCode', '未知错误')}", 'src': src, 'dest': dest}
            
    def update_translation_result(self, result):
        """更新翻译结果到UI"""
        self.target_text.config(state='normal')
        self.target_text.delete('1.0', tk.END)
        self.target_text.insert('1.0', result.get('translated', ''))
        self.target_text.config(state='normal')
        
        # 更新发音
        if 'pronunciation' in result and result['pronunciation']:
            self.pronunciation_var.set(result['pronunciation'])
            
    def add_to_history(self, source, target, src_lang, dest_lang):
        """添加到历史记录"""
        if not self.config['save_history']:
            return
            
        # 创建历史记录
        history_item = {
            'id': len(self.translation_history) + 1,
            'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            'source': source,
            'target': target,
            'src_lang': src_lang,
            'dest_lang': dest_lang
        }
        
        # 添加到列表
        self.translation_history.append(history_item)
        
        # 限制历史记录数量
        if len(self.translation_history) > self.config['max_history']:
            self.translation_history = self.translation_history[-self.config['max_history']:]
            
        # 更新Treeview
        self.update_history_tree()
        
        # 保存历史记录
        self.save_history()
        
    def update_history_tree(self):
        """更新历史记录树"""
        # 清空Treeview
        for item in self.history_tree.get_children():
            self.history_tree.delete(item)
            
        # 添加新项目（显示最近20条）
        for item in self.translation_history[-20:]:
            self.history_tree.insert('', 'end', values=(
                item['timestamp'],
                item['source'][:50] + ('...' if len(item['source']) > 50 else ''),
                item['target'][:50] + ('...' if len(item['target']) > 50 else ''),
                LANGUAGES.get(item['src_lang'], item['src_lang']),
                LANGUAGES.get(item['dest_lang'], item['dest_lang'])
            ))
            
    def on_history_double_click(self, event):
        """历史记录双击事件"""
        selection = self.history_tree.selection()
        if selection:
            item = self.history_tree.item(selection[0])
            values = item['values']
            
            # 创建详细查看窗口
            self.show_history_detail(values)
            
    def show_history_detail(self, values):
        """显示历史记录详情"""
        detail_win = tk.Toplevel(self.root)
        detail_win.title("翻译详情")
        detail_win.geometry("600x400")
        
        # 时间
        ttk.Label(detail_win, text=f"时间: {values[0]}", font=('Arial', 10, 'bold')).pack(anchor='w', padx=10, pady=5)
        
        # 源语言和目标语言
        ttk.Label(detail_win, text=f"{values[3]} → {values[4]}").pack(anchor='w', padx=10, pady=2)
        
        # 原文
        ttk.Label(detail_win, text="原文:", font=('Arial', 10, 'bold')).pack(anchor='w', padx=10, pady=(10, 2))
        source_text = scrolledtext.ScrolledText(detail_win, wrap=tk.WORD, height=8)
        source_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=(0, 5))
        source_text.insert('1.0', self.find_full_text(values[0], 'source'))
        source_text.config(state='disabled')
        
        # 译文
        ttk.Label(detail_win, text="译文:", font=('Arial', 10, 'bold')).pack(anchor='w', padx=10, pady=(5, 2))
        target_text = scrolledtext.ScrolledText(detail_win, wrap=tk.WORD, height=8)
        target_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=(0, 10))
        target_text.insert('1.0', self.find_full_text(values[0], 'target'))
        target_text.config(state='disabled')
        
        # 按钮
        btn_frame = ttk.Frame(detail_win)
        btn_frame.pack(fill=tk.X, padx=10, pady=(0, 10))
        
        ttk.Button(btn_frame, text="使用原文", command=lambda: self.use_history_source_from_detail(detail_win, values[0])).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(btn_frame, text="使用译文", command=lambda: self.use_history_target_from_detail(detail_win, values[0])).pack(side=tk.LEFT)
        
    def find_full_text(self, timestamp, text_type):
        """根据时间戳查找完整文本"""
        for item in self.translation_history:
            if item['timestamp'] == timestamp:
                if text_type == 'source':
                    return item['source']
                else:
                    return item['target']
        return ''
        
    def use_history_source(self):
        """使用历史记录的原文"""
        selection = self.history_tree.selection()
        if selection:
            item = self.history_tree.item(selection[0])
            timestamp = item['values'][0]
            
            for history_item in self.translation_history:
                if history_item['timestamp'] == timestamp:
                    self.source_text.delete('1.0', tk.END)
                    self.source_text.insert('1.0', history_item['source'])
                    self.manual_translate()
                    break
                    
    def use_history_target(self):
        """使用历史记录的译文"""
        selection = self.history_tree.selection()
        if selection:
            item = self.history_tree.item(selection[0])
            timestamp = item['values'][0]
            
            for history_item in self.translation_history:
                if history_item['timestamp'] == timestamp:
                    self.target_text.delete('1.0', tk.END)
                    self.target_text.insert('1.0', history_item['target'])
                    break
                    
    def use_history_source_from_detail(self, window, timestamp):
        """从详情窗口使用原文"""
        for history_item in self.translation_history:
            if history_item['timestamp'] == timestamp:
                self.source_text.delete('1.0', tk.END)
                self.source_text.insert('1.0', history_item['source'])
                self.manual_translate()
                window.destroy()
                break
                
    def use_history_target_from_detail(self, window, timestamp):
        """从详情窗口使用译文"""
        for history_item in self.translation_history:
            if history_item['timestamp'] == timestamp:
                self.target_text.delete('1.0', tk.END)
                self.target_text.insert('1.0', history_item['target'])
                window.destroy()
                break
                
    def delete_history_item(self):
        """删除历史记录项"""
        selection = self.history_tree.selection()
        if selection:
            if messagebox.askyesno("确认", "确定要删除这条历史记录吗？"):
                item = self.history_tree.item(selection[0])
                timestamp = item['values'][0]
                
                # 从列表中删除
                self.translation_history = [h for h in self.translation_history if h['timestamp'] != timestamp]
                
                # 更新Treeview
                self.update_history_tree()
                
                # 保存历史记录
                self.save_history()
                
    def copy_text(self, text_type):
        """复制文本"""
        if text_type == 'source':
            text = self.source_text.get('1.0', tk.END).strip()
        else:  # target
            text = self.target_text.get('1.0', tk.END).strip()
            
        if text:
            pyperclip.copy(text)
            self.status_var.set("已复制到剪贴板")
            
    def copy_translation(self):
        """复制译文"""
        self.copy_text('target')
        
    def paste_to_source(self):
        """粘贴到原文"""
        try:
            clipboard_text = pyperclip.paste()
            if clipboard_text:
                self.source_text.delete('1.0', tk.END)
                self.source_text.insert('1.0', clipboard_text)
                if self.auto_translate_var.get():
                    self.manual_translate()
        except:
            pass
            
    def clear_input(self):
        """清空输入"""
        self.source_text.delete('1.0', tk.END)
        self.target_text.delete('1.0', tk.END)
        self.pronunciation_var.set('')
        
    def clear_source(self):
        """清空原文"""
        self.source_text.delete('1.0', tk.END)
        
    def clear_history(self):
        """清空历史记录"""
        if messagebox.askyesno("确认", "确定要清空所有历史记录吗？"):
            self.translation_history.clear()
            self.update_history_tree()
            self.save_history()
            
    def open_file(self):
        """打开文件"""
        filetypes = [
            ('文本文件', '*.txt'),
            ('所有文件', '*.*')
        ]
        
        filepath = filedialog.askopenfilename(filetypes=filetypes)
        if filepath:
            try:
                with open(filepath, 'r', encoding='utf-8') as f:
                    content = f.read()
                    
                self.source_text.delete('1.0', tk.END)
                self.source_text.insert('1.0', content)
                
                if self.auto_translate_var.get():
                    self.manual_translate()
                    
                self.status_var.set(f"已加载文件: {os.path.basename(filepath)}")
            except Exception as e:
                messagebox.showerror("错误", f"无法读取文件: {e}")
                
    def save_translation(self):
        """保存翻译"""
        source_text = self.source_text.get('1.0', tk.END).strip()
        target_text = self.target_text.get('1.0', tk.END).strip()
        
        if not source_text and not target_text:
            messagebox.showwarning("提示", "没有内容可保存")
            return
            
        filetypes = [
            ('文本文件', '*.txt'),
            ('所有文件', '*.*')
        ]
        
        filepath = filedialog.asksaveasfilename(
            defaultextension='.txt',
            filetypes=filetypes
        )
        
        if filepath:
            try:
                with open(filepath, 'w', encoding='utf-8') as f:
                    f.write("=== 原文 ===\n")
                    f.write(source_text + "\n\n")
                    f.write("=== 译文 ===\n")
                    f.write(target_text + "\n\n")
                    f.write(f"=== 翻译信息 ===\n")
                    f.write(f"时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
                    f.write(f"从: {LANGUAGES.get(self.source_lang_var.get(), self.source_lang_var.get())}\n")
                    f.write(f"到: {LANGUAGES.get(self.target_lang_var.get(), self.target_lang_var.get())}\n")
                    f.write(f"引擎: {self.engine_var.get()}\n")
                    
                self.status_var.set(f"已保存到: {os.path.basename(filepath)}")
            except Exception as e:
                messagebox.showerror("错误", f"保存失败: {e}")
                
    def export_history(self):
        """导出历史记录"""
        if not self.translation_history:
            messagebox.showinfo("提示", "没有历史记录可导出")
            return
            
        filetypes = [
            ('JSON文件', '*.json'),
            ('文本文件', '*.txt'),
            ('所有文件', '*.*')
        ]
        
        filepath = filedialog.asksaveasfilename(
            defaultextension='.json',
            filetypes=filetypes
        )
        
        if filepath:
            try:
                with open(filepath, 'w', encoding='utf-8') as f:
                    json.dump(self.translation_history, f, ensure_ascii=False, indent=2)
                    
                self.status_var.set(f"历史记录已导出到: {os.path.basename(filepath)}")
            except Exception as e:
                messagebox.showerror("错误", f"导出失败: {e}")
                
    def import_history(self):
        """导入历史记录"""
        filetypes = [
            ('JSON文件', '*.json'),
            ('文本文件', '*.txt'),
            ('所有文件', '*.*')
        ]
        
        filepath = filedialog.askopenfilename(filetypes=filetypes)
        
        if filepath:
            try:
                with open(filepath, 'r', encoding='utf-8') as f:
                    imported_history = json.load(f)
                    
                if isinstance(imported_history, list):
                    self.translation_history.extend(imported_history)
                    # 限制总数
                    if len(self.translation_history) > self.config['max_history']:
                        self.translation_history = self.translation_history[-self.config['max_history']:]
                        
                    self.update_history_tree()
                    self.save_history()
                    
                    messagebox.showinfo("成功", f"已导入 {len(imported_history)} 条历史记录")
                else:
                    messagebox.showerror("错误", "文件格式不正确")
            except Exception as e:
                messagebox.showerror("错误", f"导入失败: {e}")
                
    def open_settings(self):
        """打开设置窗口"""
        settings_win = tk.Toplevel(self.root)
        settings_win.title("设置")
        settings_win.geometry("500x400")
        settings_win.transient(self.root)
        settings_win.grab_set()
        
        # 创建笔记本
        notebook = ttk.Notebook(settings_win)
        notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 基本设置标签页
        basic_frame = ttk.Frame(notebook)
        notebook.add(basic_frame, text="基本")
        
        # 翻译设置
        ttk.Label(basic_frame, text="翻译设置:", font=('Arial', 10, 'bold')).grid(row=0, column=0, columnspan=2, sticky='w', pady=(10, 5))
        
        # 自动翻译
        auto_translate_var = tk.BooleanVar(value=self.config['auto_translate'])
        auto_translate_cb = ttk.Checkbutton(basic_frame, text="自动翻译", variable=auto_translate_var)
        auto_translate_cb.grid(row=1, column=0, sticky='w', padx=10, pady=2)
        
        # 自动复制
        auto_copy_var = tk.BooleanVar(value=self.config['auto_copy'])
        auto_copy_cb = ttk.Checkbutton(basic_frame, text="翻译后自动复制", variable=auto_copy_var)
        auto_copy_cb.grid(row=2, column=0, sticky='w', padx=10, pady=2)
        
        # 自动发音
        auto_sound_var = tk.BooleanVar(value=self.config['auto_play_sound'])
        auto_sound_cb = ttk.Checkbutton(basic_frame, text="翻译后自动发音", variable=auto_sound_var)
        auto_sound_cb.grid(row=3, column=0, sticky='w', padx=10, pady=2)
        
        # 显示发音
        show_pron_var = tk.BooleanVar(value=self.config['show_pronunciation'])
        show_pron_cb = ttk.Checkbutton(basic_frame, text="显示发音", variable=show_pron_var)
        show_pron_cb.grid(row=4, column=0, sticky='w', padx=10, pady=2)
        
        # 保存历史
        save_history_var = tk.BooleanVar(value=self.config['save_history'])
        save_history_cb = ttk.Checkbutton(basic_frame, text="保存历史记录", variable=save_history_var)
        save_history_cb.grid(row=5, column=0, sticky='w', padx=10, pady=2)
        
        # 历史记录最大数量
        ttk.Label(basic_frame, text="最大历史记录:").grid(row=6, column=0, sticky='w', padx=10, pady=2)
        max_history_var = tk.StringVar(value=str(self.config['max_history']))
        max_history_spin = ttk.Spinbox(basic_frame, from_=10, to=10000, textvariable=max_history_var, width=10)
        max_history_spin.grid(row=6, column=1, sticky='w', padx=10, pady=2)
        
        # 字体大小
        ttk.Label(basic_frame, text="字体大小:").grid(row=7, column=0, sticky='w', padx=10, pady=2)
        font_size_var = tk.StringVar(value=str(self.config['font_size']))
        font_size_spin = ttk.Spinbox(basic_frame, from_=8, to=24, textvariable=font_size_var, width=10)
        font_size_spin.grid(row=7, column=1, sticky='w', padx=10, pady=2)
        
        # API设置标签页
        api_frame = ttk.Frame(notebook)
        notebook.add(api_frame, text="API")
        
        ttk.Label(api_frame, text="百度翻译API:", font=('Arial', 10, 'bold')).grid(row=0, column=0, sticky='w', padx=10, pady=(10, 5))
        
        ttk.Label(api_frame, text="App ID:").grid(row=1, column=0, sticky='w', padx=20, pady=2)
        baidu_appid_var = tk.StringVar()
        baidu_appid_entry = ttk.Entry(api_frame, textvariable=baidu_appid_var, width=30)
        baidu_appid_entry.grid(row=1, column=1, sticky='w', padx=10, pady=2)
        
        ttk.Label(api_frame, text="密钥:").grid(row=2, column=0, sticky='w', padx=20, pady=2)
        baidu_secret_var = tk.StringVar()
        baidu_secret_entry = ttk.Entry(api_frame, textvariable=baidu_secret_var, width=30, show="*")
        baidu_secret_entry.grid(row=2, column=1, sticky='w', padx=10, pady=2)
        
        ttk.Label(api_frame, text="有道翻译API:", font=('Arial', 10, 'bold')).grid(row=3, column=0, sticky='w', padx=10, pady=(10, 5))
        
        ttk.Label(api_frame, text="App Key:").grid(row=4, column=0, sticky='w', padx=20, pady=2)
        youdao_key_var = tk.StringVar()
        youdao_key_entry = ttk.Entry(api_frame, textvariable=youdao_key_var, width=30)
        youdao_key_entry.grid(row=4, column=1, sticky='w', padx=10, pady=2)
        
        ttk.Label(api_frame, text="密钥:").grid(row=5, column=0, sticky='w', padx=20, pady=2)
        youdao_secret_var = tk.StringVar()
        youdao_secret_entry = ttk.Entry(api_frame, textvariable=youdao_secret_var, width=30, show="*")
        youdao_secret_entry.grid(row=5, column=1, sticky='w', padx=10, pady=2)
        
        # 按钮
        btn_frame = ttk.Frame(settings_win)
        btn_frame.pack(fill=tk.X, padx=10, pady=10)
        
        def save_settings():
            """保存设置"""
            self.config['auto_translate'] = auto_translate_var.get()
            self.config['auto_copy'] = auto_copy_var.get()
            self.config['auto_play_sound'] = auto_sound_var.get()
            self.config['show_pronunciation'] = show_pron_var.get()
            self.config['save_history'] = save_history_var.get()
            
            try:
                self.config['max_history'] = int(max_history_var.get())
            except:
                self.config['max_history'] = 1000
                
            try:
                self.config['font_size'] = int(font_size_var.get())
            except:
                self.config['font_size'] = 12
                
            # 更新UI
            self.auto_translate_var.set(self.config['auto_translate'])
            
            # 更新字体大小
            self.source_text.config(font=('Microsoft YaHei', self.config['font_size']))
            self.target_text.config(font=('Microsoft YaHei', self.config['font_size']))
            
            # 保存配置
            self.save_config()
            
            settings_win.destroy()
            messagebox.showinfo("成功", "设置已保存")
            
        ttk.Button(btn_frame, text="保存", command=save_settings).pack(side=tk.RIGHT, padx=5)
        ttk.Button(btn_frame, text="取消", command=settings_win.destroy).pack(side=tk.RIGHT, padx=5)
        
    def detect_language(self):
        """检测语言"""
        text = self.source_text.get('1.0', tk.END).strip()
        if not text:
            messagebox.showinfo("提示", "请输入要检测的文本")
            return
            
        try:
            translator = self.translators['google']
            result = translator.detect(text)
            
            messagebox.showinfo("语言检测", 
                              f"检测到的语言: {LANGUAGES.get(result.lang, result.lang)}\n"
                              f"置信度: {result.confidence}")
        except Exception as e:
            messagebox.showerror("错误", f"语言检测失败: {e}")
            
    def text_to_speech(self, text_type='target'):
        """文本转语音"""
        if text_type == 'source':
            text = self.source_text.get('1.0', tk.END).strip()
        else:
            text = self.target_text.get('1.0', tk.END).strip()
            
        if not text:
            messagebox.showinfo("提示", "没有要朗读的文本")
            return
            
        if not self.tts_engine:
            messagebox.showerror("错误", "TTS引擎未初始化")
            return
            
        try:
            # 启动新线程播放语音
            threading.Thread(target=self._play_speech, args=(text,), daemon=True).start()
        except Exception as e:
            messagebox.showerror("错误", f"语音播放失败: {e}")
            
    def _play_speech(self, text):
        """播放语音"""
        try:
            self.tts_engine.say(text)
            self.tts_engine.runAndWait()
        except Exception as e:
            logger.error(f"语音播放失败: {e}")
            
    def play_sound(self, text_type):
        """播放语音（UI调用）"""
        self.text_to_speech(text_type)
        
    def show_help(self):
        """显示帮助"""
        help_text = """智能翻译助手 使用说明

基本功能：
1. 在左侧输入原文，右侧显示译文
2. 选择源语言和目标语言
3. 支持自动翻译（输入时自动翻译）
4. 支持手动翻译（点击翻译按钮）

快捷键：
Ctrl+T: 翻译
Ctrl+S: 保存翻译
Ctrl+O: 打开文件
Ctrl+C: 复制译文
Ctrl+V: 粘贴到原文
Ctrl+L: 清空输入
F1: 显示帮助

翻译引擎：
1. Google翻译（免费，无需API）
2. 百度翻译（需要API）
3. 有道翻译（需要API）

其他功能：
1. 翻译历史记录
2. 文本转语音
3. 语言检测
4. 导出/导入历史记录
5. 文件导入/导出
"""
        messagebox.showinfo("使用说明", help_text)
        
    def show_about(self):
        """显示关于"""
        about_text = """智能翻译助手 v2.0

一个功能强大的翻译工具，支持多种翻译引擎。

功能特点：
- 支持Google、百度、有道翻译
- 实时翻译和历史记录
- 文本转语音功能
- 文件导入导出
- 多种实用工具

作者: AI助手
版本: 2.0.0
"""
        messagebox.showinfo("关于", about_text)
        
    def load_config(self):
        """加载配置"""
        try:
            if os.path.exists('translation_config.json'):
                with open('translation_config.json', 'r', encoding='utf-8') as f:
                    loaded_config = json.load(f)
                    self.config.update(loaded_config)
        except Exception as e:
            logger.error(f"加载配置失败: {e}")
            
    def save_config(self):
        """保存配置"""
        try:
            with open('translation_config.json', 'w', encoding='utf-8') as f:
                json.dump(self.config, f, ensure_ascii=False, indent=2)
        except Exception as e:
            logger.error(f"保存配置失败: {e}")
            
    def load_history(self):
        """加载历史记录"""
        try:
            if os.path.exists('translation_history.json'):
                with open('translation_history.json', 'r', encoding='utf-8') as f:
                    self.translation_history = json.load(f)
        except Exception as e:
            logger.error(f"加载历史记录失败: {e}")
            self.translation_history = []
            
    def save_history(self):
        """保存历史记录"""
        if not self.config['save_history']:
            return
            
        try:
            with open('translation_history.json', 'w', encoding='utf-8') as f:
                json.dump(self.translation_history, f, ensure_ascii=False, indent=2)
        except Exception as e:
            logger.error(f"保存历史记录失败: {e}")
            
    def on_closing(self):
        """关闭程序"""
        self.running = False
        if self.translation_thread.is_alive():
            self.translation_thread.join(timeout=1)
        self.save_config()
        self.save_history()
        self.root.destroy()
        
    def run(self):
        """运行程序"""
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.root.mainloop()

# 主程序入口
if __name__ == "__main__":
    root = tk.Tk()
    app = TranslationApp(root)
    app.run()