#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
智能翻译工具 v2.5
"""

import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox, filedialog
import json
import os
import threading
import queue
import re
from datetime import datetime
from collections import OrderedDict
import urllib.request
import urllib.parse
import urllib.error
import ssl
import socket

# ==================== 基础常量 ====================
APP_NAME = "智能翻译工具 v2.5"
WINDOW_WIDTH = 900
WINDOW_HEIGHT = 700
CONFIG_FILE = "translator_config.json"
HISTORY_FILE = "history.json"
DICT_FILE = "dictionary.json"

LANGUAGES = OrderedDict([
    ("自动检测", "auto"),
    ("中文", "zh"),
    ("英语", "en"),
    ("日语", "ja"),
    ("韩语", "ko"),
    ("法语", "fr"),
    ("德语", "de"),
    ("西班牙语", "es"),
    ("俄语", "ru"),
])

# ==================== 网络请求工具 ====================
class HttpUtil:
    @staticmethod
    def get(url, params=None, timeout=8):
        if params:
            query_string = urllib.parse.urlencode(params)
            full_url = f"{url}?{query_string}"
        else:
            full_url = url
        req = urllib.request.Request(
            full_url,
            headers={
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
                "Accept": "application/json, text/plain, */*",
            }
        )
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        try:
            response = urllib.request.urlopen(req, timeout=timeout, context=ctx)
            return response.read().decode("utf-8", errors="replace")
        except urllib.error.HTTPError as e:
            raise Exception(f"HTTP错误 {e.code}")
        except urllib.error.URLError as e:
            raise Exception(f"网络错误: {e.reason}")
        except socket.timeout:
            raise Exception("连接超时")
        except Exception as e:
            raise Exception(str(e))

    @staticmethod
    def post(url, data=None, timeout=8, is_json=False):
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
            "Accept": "application/json, text/plain, */*",
        }
        if is_json:
            headers["Content-Type"] = "application/json;charset=utf-8"
            post_data = json.dumps(data).encode("utf-8")
        else:
            headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8"
            post_data = urllib.parse.urlencode(data).encode("utf-8") if data else b""
        req = urllib.request.Request(url, data=post_data, headers=headers, method="POST")
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        try:
            response = urllib.request.urlopen(req, timeout=timeout, context=ctx)
            return response.read().decode("utf-8", errors="replace")
        except urllib.error.HTTPError as e:
            raise Exception(f"HTTP错误 {e.code}")
        except urllib.error.URLError as e:
            raise Exception(f"网络错误: {e.reason}")
        except socket.timeout:
            raise Exception("连接超时")
        except Exception as e:
            raise Exception(str(e))

# ==================== 在线翻译引擎 ====================
class OnlineTranslator:
    def __init__(self):
        self.name = "在线翻译"

    def translate(self, text, source_lang, target_lang):
        errors = []
        try:
            result = self._mymemory(text, source_lang, target_lang)
            if result and result.strip():
                return result.strip()
        except Exception as e:
            errors.append(f"MyMemory: {str(e)[:30]}")
        try:
            result = self._baidu_simulate(text, source_lang, target_lang)
            if result and result.strip():
                return result.strip()
        except Exception as e:
            errors.append(f"百度: {str(e)[:30]}")
        try:
            result = self._youdao_simulate(text, source_lang, target_lang)
            if result and result.strip():
                return result.strip()
        except Exception as e:
            errors.append(f"有道: {str(e)[:30]}")
        try:
            result = self._tencent_simulate(text, source_lang, target_lang)
            if result and result.strip():
                return result.strip()
        except Exception as e:
            errors.append(f"腾讯: {str(e)[:30]}")
        try:
            result = self._lingva(text, source_lang, target_lang)
            if result and result.strip():
                return result.strip()
        except Exception as e:
            errors.append(f"Lingva: {str(e)[:30]}")
        try:
            local = LocalTranslator()
            result = local.translate(text, source_lang, target_lang)
            if result and "[未找到翻译]" not in result:
                return result
        except:
            pass
        error_msg = "\n".join(errors) if errors else "所有翻译源均不可用"
        raise Exception(f"翻译失败:\n{error_msg}\n\n请检查网络连接")

    def _mymemory(self, text, source_lang, target_lang):
        url = "https://api.mymemory.translated.net/get"
        lang_pair = f"{source_lang}|{target_lang}" if source_lang != "auto" else f"auto|{target_lang}"
        params = {"q": text, "langpair": lang_pair, "mt": "1"}
        raw = HttpUtil.get(url, params, timeout=6)
        data = json.loads(raw)
        if data.get("responseStatus") == 200:
            matches = data.get("matches", [])
            if matches:
                return matches[0].get("translation", "")
        return None

    def _baidu_simulate(self, text, source_lang, target_lang):
        url = "https://fanyi.baidu.com/sug"
        raw = HttpUtil.post(url, {"kw": text}, timeout=5)
        result = json.loads(raw)
        if result.get("errno") == 0 and result.get("data"):
            return "\n".join([i["v"] for i in result["data"]])
        return None

    def _youdao_simulate(self, text, source_lang, target_lang):
        url = "https://dict.youdao.com/jsonapi_s?doctype=json&jsonversion=4"
        raw = HttpUtil.post(url, {"q": text, "dicts": '{"count":99,"dicts":[["ec","ce"]]}'}, timeout=5)
        res = json.loads(raw)
        trans_list = []
        if res.get("ec", {}).get("word"):
            for tr in res["ec"]["word"][0].get("trs", []):
                trans_list.append(tr["tr"][0]["l"]["i"])
        if res.get("ce", {}).get("word"):
            for tr in res["ce"]["word"][0].get("trs", []):
                trans_list.append(tr["tr"][0]["l"]["i"])
        return "\n".join(trans_list) if trans_list else None

    def _tencent_simulate(self, text, source_lang, target_lang):
        url = "https://transmart.qq.com/api/imt"
        data = {
            "destText": "", "reqText": text,
            "destLang": target_lang,
            "sourceLang": source_lang if source_lang != "auto" else "zh",
            "sessionUuid": "translate_uuid"
        }
        raw = HttpUtil.post(url, data, timeout=5, is_json=True)
        res = json.loads(raw)
        if res.get("returnCode") == 0:
            return res.get("translateResult", {}).get("destText", "")
        return None

    def _lingva(self, text, source_lang, target_lang):
        mirrors = ["https://lingva.ml", "https://translate.projectsegfau.lt"]
        sl = source_lang if source_lang != "auto" else "auto"
        tl = target_lang
        encode_txt = urllib.parse.quote(text)
        for m in mirrors:
            try:
                resp = HttpUtil.get(f"{m}/api/v1/{sl}/{tl}/{encode_txt}", timeout=5)
                return json.loads(resp)["translation"]
            except:
                continue
        return None

    def detect_language(self, text):
        if not text:
            return "en"
        zh = len(re.findall(r'[\u4e00-\u9fff]', text))
        ja = len(re.findall(r'[\u3040-\u30ff]', text))
        ko = len(re.findall(r'[\uac00-\ud7af]', text))
        ru = len(re.findall(r'[а-яА-Я]', text))
        total = len(text.strip())
        if total == 0: return "en"
        if zh / total > 0.3: return "zh"
        if ja / total > 0.3: return "ja"
        if ko / total > 0.3: return "ko"
        if ru / total > 0.3: return "ru"
        return "en"

# ==================== 本地词典 ====================
class LocalTranslator:
    def __init__(self):
        self.name = "本地词典"
        self.default_words = {
            "hello": "你好", "hi": "你好", "hey": "嘿",
            "goodbye": "再见", "bye": "再见", "farewell": "告别",
            "yes": "是的", "no": "不", "ok": "好的", "okay": "好的",
            "please": "请", "thank": "谢谢", "thanks": "谢谢",
            "sorry": "对不起", "excuse": "原谅", "pardon": "原谅",
            "help": "帮助", "save": "保存", "stop": "停止",
            "start": "开始", "begin": "开始", "end": "结束",
            "finish": "完成", "continue": "继续", "pause": "暂停",
            
            # === 人称代词 ===
            "i": "我", "you": "你", "he": "他", "she": "她",
            "it": "它", "we": "我们", "they": "他们",
            "me": "我", "him": "他", "her": "她", "us": "我们",
            "them": "他们", "my": "我的", "your": "你的",
            "his": "他的", "her": "她的", "its": "它的",
            "our": "我们的", "their": "他们的",
            "myself": "我自己", "yourself": "你自己",
            "himself": "他自己", "herself": "她自己",
            "itself": "它自己", "ourselves": "我们自己",
            "themselves": "他们自己",
            
            # === 疑问词 ===
            "what": "什么", "who": "谁", "whom": "谁",
            "whose": "谁的", "which": "哪个", "where": "哪里",
            "when": "什么时候", "why": "为什么", "how": "如何",
            "whether": "是否", "whatever": "无论什么",
            "whoever": "无论谁", "wherever": "无论哪里",
            "whenever": "无论何时", "however": "然而",
            
            # === 冠词/限定词 ===
            "a": "一个", "an": "一个", "the": "这个",
            "this": "这个", "that": "那个", "these": "这些",
            "those": "那些", "some": "一些", "any": "任何",
            "many": "许多", "much": "很多", "few": "很少",
            "several": "几个", "all": "全部", "every": "每个",
            "each": "每个", "both": "两者", "neither": "两者都不",
            "either": "任一", "none": "没有一个",
            
            # === 形容词 ===
            "good": "好", "bad": "坏", "great": "很棒",
            "excellent": "优秀", "wonderful": "精彩",
            "beautiful": "美丽", "pretty": "漂亮", "handsome": "英俊",
            "ugly": "丑陋", "nice": "好", "kind": "善良",
            "smart": "聪明", "clever": "聪明", "wise": "智慧",
            "stupid": "愚蠢", "silly": "傻", "crazy": "疯狂",
            "funny": "有趣", "happy": "快乐", "sad": "悲伤",
            "angry": "生气", "mad": "疯了", "glad": "高兴",
            "tired": "累", "sleepy": "困", "hungry": "饿",
            "thirsty": "渴", "full": "饱", "empty": "空",
            "big": "大", "small": "小", "large": "大",
            "tiny": "极小", "huge": "巨大", "giant": "巨大",
            "long": "长", "short": "短", "tall": "高",
            "high": "高", "low": "低", "wide": "宽",
            "narrow": "窄", "deep": "深", "shallow": "浅",
            "thick": "厚", "thin": "薄", "fat": "胖",
            "heavy": "重", "light": "轻", "hard": "硬",
            "soft": "软", "smooth": "光滑", "rough": "粗糙",
            "wet": "湿", "dry": "干", "clean": "干净",
            "dirty": "脏", "new": "新", "old": "旧",
            "young": "年轻", "fresh": "新鲜", "stale": "不新鲜",
            "fast": "快", "slow": "慢", "quick": "快速",
            "early": "早", "late": "晚", "soon": "很快",
            "near": "近", "far": "远", "close": "接近",
            "hot": "热", "cold": "冷", "warm": "温暖",
            "cool": "凉爽", "freezing": "冰冻", "boiling": "沸腾",
            "rich": "富有", "poor": "贫穷", "cheap": "便宜",
            "expensive": "昂贵", "free": "免费", "valuable": "有价值",
            "important": "重要", "necessary": "必要",
            "possible": "可能", "impossible": "不可能",
            "true": "真实", "false": "虚假", "real": "真的",
            "correct": "正确", "wrong": "错误", "right": "对",
            "easy": "容易", "difficult": "困难", "simple": "简单",
            "complex": "复杂", "safe": "安全", "dangerous": "危险",
            "strong": "强壮", "weak": "虚弱", "powerful": "强大",
            "popular": "流行", "famous": "著名", "common": "常见",
            "rare": "稀有", "special": "特别", "usual": "通常",
            "normal": "正常", "strange": "奇怪", "weird": "古怪",
            "different": "不同", "same": "相同", "similar": "相似",
            "unique": "独特", "perfect": "完美", "whole": "整个",
            "single": "单一", "double": "双倍", "multiple": "多个",
            
            # === 颜色 ===
            "red": "红色", "blue": "蓝色", "green": "绿色",
            "yellow": "黄色", "white": "白色", "black": "黑色",
            "gray": "灰色", "grey": "灰色", "brown": "棕色",
            "pink": "粉色", "purple": "紫色", "orange": "橙色",
            "gold": "金色", "silver": "银色", "dark": "深色",
            "light": "浅色", "bright": "明亮", "colorful": "多彩",
            
            # === 数字 ===
            "zero": "零", "one": "一", "two": "二", "three": "三",
            "four": "四", "five": "五", "six": "六", "seven": "七",
            "eight": "八", "nine": "九", "ten": "十",
            "eleven": "十一", "twelve": "十二", "thirteen": "十三",
            "fourteen": "十四", "fifteen": "十五", "sixteen": "十六",
            "seventeen": "十七", "eighteen": "十八", "nineteen": "十九",
            "twenty": "二十", "thirty": "三十", "forty": "四十",
            "fifty": "五十", "sixty": "六十", "seventy": "七十",
            "eighty": "八十", "ninety": "九十",
            "hundred": "百", "thousand": "千", "million": "百万",
            "billion": "十亿", "first": "第一", "second": "第二",
            "third": "第三", "last": "最后", "next": "下一个",
            
            # === 时间 ===
            "time": "时间", "day": "天", "night": "夜晚",
            "morning": "早上", "afternoon": "下午", "evening": "晚上",
            "today": "今天", "tomorrow": "明天", "yesterday": "昨天",
            "week": "周", "month": "月", "year": "年",
            "hour": "小时", "minute": "分钟", "second": "秒",
            "moment": "时刻", "period": "时期", "age": "年龄",
            "date": "日期", "calendar": "日历", "clock": "时钟",
            "spring": "春天", "summer": "夏天", "autumn": "秋天",
            "fall": "秋天", "winter": "冬天",
            "january": "一月", "february": "二月", "march": "三月",
            "april": "四月", "may": "五月", "june": "六月",
            "july": "七月", "august": "八月", "september": "九月",
            "october": "十月", "november": "十一月", "december": "十二月",
            "monday": "星期一", "tuesday": "星期二", "wednesday": "星期三",
            "thursday": "星期四", "friday": "星期五", "saturday": "星期六",
            "sunday": "星期日", "weekend": "周末", "weekday": "工作日",
            "birthday": "生日", "holiday": "假日", "vacation": "假期",
            
            # === 食物 ===
            "food": "食物", "water": "水", "tea": "茶",
            "coffee": "咖啡", "milk": "牛奶", "juice": "果汁",
            "bread": "面包", "rice": "米饭", "noodle": "面条",
            "meat": "肉", "fish": "鱼", "chicken": "鸡肉",
            "beef": "牛肉", "pork": "猪肉", "egg": "鸡蛋",
            "vegetable": "蔬菜", "fruit": "水果", "apple": "苹果",
            "banana": "香蕉", "orange": "橙子", "grape": "葡萄",
            "strawberry": "草莓", "watermelon": "西瓜",
            "cake": "蛋糕", "cookie": "饼干", "candy": "糖果",
            "chocolate": "巧克力", "ice cream": "冰淇淋",
            "soup": "汤", "salad": "沙拉", "pizza": "披萨",
            "burger": "汉堡", "sandwich": "三明治",
            "breakfast": "早餐", "lunch": "午餐", "dinner": "晚餐",
            "delicious": "美味", "tasty": "好吃", "yummy": "好吃",
            "sweet": "甜", "sour": "酸", "salty": "咸",
            "bitter": "苦", "spicy": "辣", "fresh": "新鲜",
            
            # === 动物 ===
            "animal": "动物", "dog": "狗", "cat": "猫",
            "bird": "鸟", "fish": "鱼", "horse": "马",
            "cow": "牛", "pig": "猪", "sheep": "羊",
            "rabbit": "兔子", "duck": "鸭子", "chicken": "鸡",
            "mouse": "老鼠", "rat": "老鼠", "snake": "蛇",
            "frog": "青蛙", "turtle": "乌龟", "butterfly": "蝴蝶",
            "bee": "蜜蜂", "ant": "蚂蚁", "spider": "蜘蛛",
            "lion": "狮子", "tiger": "老虎", "bear": "熊",
            "wolf": "狼", "fox": "狐狸", "deer": "鹿",
            "monkey": "猴子", "elephant": "大象", "giraffe": "长颈鹿",
            "panda": "熊猫", "dolphin": "海豚", "whale": "鲸鱼",
            "eagle": "鹰", "owl": "猫头鹰", "parrot": "鹦鹉",
            "penguin": "企鹅", "shark": "鲨鱼", "crab": "螃蟹",
            
            # === 身体部位 ===
            "head": "头", "face": "脸", "eye": "眼睛",
            "nose": "鼻子", "mouth": "嘴", "ear": "耳朵",
            "hair": "头发", "neck": "脖子", "shoulder": "肩膀",
            "arm": "手臂", "hand": "手", "finger": "手指",
            "leg": "腿", "foot": "脚", "knee": "膝盖",
            "toe": "脚趾", "back": "背", "chest": "胸",
            "heart": "心脏", "brain": "大脑", "blood": "血液",
            "bone": "骨头", "skin": "皮肤", "muscle": "肌肉",
            "tooth": "牙齿", "tongue": "舌头", "lip": "嘴唇",
            
            # === 家庭 ===
            "family": "家庭", "father": "父亲", "mother": "母亲",
            "dad": "爸爸", "mom": "妈妈", "parent": "父母",
            "son": "儿子", "daughter": "女儿", "child": "孩子",
            "children": "孩子们", "baby": "婴儿", "brother": "兄弟",
            "sister": "姐妹", "husband": "丈夫", "wife": "妻子",
            "grandpa": "爷爷", "grandma": "奶奶", "grandfather": "祖父",
            "grandmother": "祖母", "uncle": "叔叔", "aunt": "阿姨",
            "cousin": "表亲", "nephew": "侄子", "niece": "侄女",
            "friend": "朋友", "boyfriend": "男朋友", "girlfriend": "女朋友",
            "neighbor": "邻居", "guest": "客人", "host": "主人",
            
            # === 职业 ===
            "teacher": "老师", "doctor": "医生", "nurse": "护士",
            "student": "学生", "worker": "工人", "farmer": "农民",
            "driver": "司机", "cook": "厨师", "waiter": "服务员",
            "actor": "演员", "singer": "歌手", "dancer": "舞者",
            "writer": "作家", "artist": "艺术家", "painter": "画家",
            "engineer": "工程师", "scientist": "科学家",
            "lawyer": "律师", "judge": "法官", "police": "警察",
            "soldier": "士兵", "pilot": "飞行员", "sailor": "水手",
            "king": "国王", "queen": "女王", "prince": "王子",
            "princess": "公主", "president": "总统", "manager": "经理",
            "boss": "老板", "secretary": "秘书", "reporter": "记者",
            
            # === 地点 ===
            "home": "家", "house": "房子", "room": "房间",
            "door": "门", "window": "窗户", "wall": "墙",
            "floor": "地板", "roof": "屋顶", "stairs": "楼梯",
            "kitchen": "厨房", "bedroom": "卧室", "bathroom": "浴室",
            "garden": "花园", "yard": "院子", "garage": "车库",
            "school": "学校", "hospital": "医院", "library": "图书馆",
            "museum": "博物馆", "park": "公园", "store": "商店",
            "shop": "店铺", "market": "市场", "mall": "商场",
            "restaurant": "餐厅", "hotel": "酒店", "bank": "银行",
            "office": "办公室", "factory": "工厂", "farm": "农场",
            "city": "城市", "town": "城镇", "village": "村庄",
            "country": "国家", "state": "州", "capital": "首都",
            "street": "街道", "road": "路", "bridge": "桥",
            "river": "河流", "lake": "湖", "sea": "海",
            "ocean": "海洋", "mountain": "山", "forest": "森林",
            "desert": "沙漠", "island": "岛屿", "beach": "海滩",
            
            # === 交通 ===
            "car": "汽车", "bus": "公交车", "train": "火车",
            "plane": "飞机", "airplane": "飞机", "ship": "船",
            "boat": "小船", "bike": "自行车", "bicycle": "自行车",
            "motorcycle": "摩托车", "taxi": "出租车", "truck": "卡车",
            "ambulance": "救护车", "fire truck": "消防车",
            "drive": "驾驶", "ride": "骑", "fly": "飞",
            "travel": "旅行", "trip": "旅程", "journey": "旅行",
            "traffic": "交通", "parking": "停车", "fuel": "燃料",
            
            # === 动词 ===
            "go": "去", "come": "来", "run": "跑", "walk": "走",
            "swim": "游泳", "jump": "跳", "sit": "坐", "stand": "站",
            "lie": "躺", "sleep": "睡觉", "wake": "醒来",
            "eat": "吃", "drink": "喝", "cook": "烹饪",
            "read": "读", "write": "写", "draw": "画",
            "sing": "唱", "dance": "跳舞", "play": "玩",
            "work": "工作", "study": "学习", "teach": "教",
            "learn": "学习", "think": "想", "know": "知道",
            "understand": "理解", "remember": "记住", "forget": "忘记",
            "believe": "相信", "feel": "感觉", "hear": "听到",
            "listen": "听", "see": "看见", "watch": "看",
            "look": "看", "speak": "说话", "talk": "谈话",
            "say": "说", "tell": "告诉", "ask": "问",
            "answer": "回答", "give": "给", "take": "拿",
            "bring": "带来", "send": "发送", "receive": "接收",
            "buy": "买", "sell": "卖", "pay": "支付",
            "find": "找到", "lose": "丢失", "search": "搜索",
            "open": "打开", "close": "关闭", "lock": "锁",
            "turn": "转动", "push": "推", "pull": "拉",
            "put": "放", "get": "得到", "make": "制作",
            "do": "做", "have": "有", "use": "使用",
            "try": "尝试", "keep": "保持", "leave": "离开",
            "stay": "停留", "wait": "等待", "hurry": "匆忙",
            "change": "改变", "fix": "修理", "break": "打破",
            "build": "建造", "create": "创造", "destroy": "破坏",
            "show": "展示", "hide": "隐藏", "share": "分享",
            "help": "帮助", "protect": "保护", "attack": "攻击",
            "win": "赢", "lose": "输", "fight": "战斗",
            "catch": "抓住", "throw": "扔", "kick": "踢",
            "hit": "打", "cut": "切", "wash": "洗",
            "clean": "打扫", "sweep": "扫地", "fold": "折叠",
            
            # === 常用短语 ===
            "how are you": "你好吗", "i am fine": "我很好",
            "thank you": "谢谢你", "you are welcome": "不客气",
            "nice to meet you": "很高兴认识你",
            "good morning": "早上好", "good afternoon": "下午好",
            "good evening": "晚上好", "good night": "晚安",
            "see you later": "回头见", "see you tomorrow": "明天见",
            "come here": "过来", "go there": "去那里",
            "help me": "帮帮我", "excuse me": "打扰一下",
            "i love you": "我爱你", "i miss you": "我想你",
            "happy birthday": "生日快乐", "merry christmas": "圣诞快乐",
            "happy new year": "新年快乐",
            "what is your name": "你叫什么名字",
            "my name is": "我叫",
            "where are you from": "你从哪里来",
            "i am from": "我来自",
            "how much": "多少钱", "how many": "多少个",
            "i dont know": "我不知道", "i understand": "我明白",
            "i dont understand": "我不明白",
            "can you help me": "你能帮我吗",
            "of course": "当然", "no problem": "没问题",
            "just a moment": "稍等一下", "wait a minute": "等一下",
            "come on": "来吧", "lets go": "走吧",
            "take care": "保重", "good luck": "好运",
            "well done": "做得好", "good job": "干得好",
            "never mind": "没关系", "dont worry": "别担心",
            "im sorry": "我很抱歉", "its okay": "没关系",
            "thats great": "太好了", "thats wonderful": "太棒了",
            "i think so": "我也这么认为",
            "i dont think so": "我不这么认为",
            "maybe": "也许", "probably": "可能",
            "certainly": "当然", "definitely": "一定",
            "absolutely": "绝对", "exactly": "正是",
            
            # === 中文到英文 ===
            "你好": "Hello", "您好": "Hello",
            "谢谢": "Thank you", "非常感谢": "Thank you very much",
            "再见": "Goodbye", "拜拜": "Bye bye",
            "对不起": "Sorry", "很抱歉": "Very sorry",
            "没关系": "It's okay", "不要紧": "Never mind",
            "请": "Please", "麻烦": "Trouble",
            "是的": "Yes", "不是": "No", "好的": "OK",
            "没错": "That's right", "不对": "Wrong",
            "我爱": "I love", "我喜欢": "I like",
            "我想要": "I want", "我需要": "I need",
            "我可以": "I can", "我会": "I will",
            "我不能": "I cannot", "我不会": "I won't",
            "今天": "Today", "明天": "Tomorrow", "昨天": "Yesterday",
            "早上好": "Good morning", "下午好": "Good afternoon",
            "晚上好": "Good evening", "晚安": "Good night",
            "生日快乐": "Happy birthday",
            "新年快乐": "Happy New Year",
            "圣诞快乐": "Merry Christmas",
            "多少钱": "How much", "在哪里": "Where is",
            "什么时候": "When", "为什么": "Why",
            "怎么样": "How", "你是谁": "Who are you",
            "你叫什么名字": "What is your name",
            "你从哪里来": "Where are you from",
            "很高兴认识你": "Nice to meet you",
            "这是什么": "What is this", "那是什么": "What is that",
            "这是什么意思": "What does this mean",
            "你能帮我吗": "Can you help me",
            "我不明白": "I don't understand",
            "请再说一遍": "Please say it again",
            "慢一点说": "Speak slowly",
            "大": "Big", "小": "Small", "好": "Good",
            "坏": "Bad", "新": "New", "旧": "Old",
            "热": "Hot", "冷": "Cold", "快": "Fast",
            "慢": "Slow", "多": "Many", "少": "Few",
            "高": "High", "低": "Low", "长": "Long",
            "短": "Short", "远": "Far", "近": "Near",
            "开": "Open", "关": "Close", "来": "Come",
            "去": "Go", "吃": "Eat", "喝": "Drink",
            "睡": "Sleep", "走": "Walk", "跑": "Run",
            "看": "Look", "听": "Listen", "说": "Say",
            "读": "Read", "写": "Write", "买": "Buy",
            "卖": "Sell", "给": "Give", "拿": "Take",
            "有": "Have", "没有": "Don't have",
            "是": "Is", "在": "At", "和": "And",
            "但是": "But", "因为": "Because", "所以": "So",
            "如果": "If", "当": "When", "虽然": "Although",
            "非常": "Very", "太": "Too", "很": "Very",
            "真": "Really", "有点": "A little", "一些": "Some",
            "所有": "All", "每个": "Every", "很多": "Many",
            "很少": "Few", "更多": "More", "更少": "Less",
            "最好": "Best", "最差": "Worst",
            "第一个": "First", "最后一个": "Last",
            "现在": "Now", "马上": "Immediately",
            "立刻": "Right away", "以后": "Later",
            "以前": "Before", "之后": "After",
            "里面": "Inside", "外面": "Outside",
            "上面": "Above", "下面": "Below",
            "左边": "Left", "右边": "Right",
            "前面": "Front", "后面": "Back",
            "中间": "Middle", "旁边": "Next to",
            "这里": "Here", "那里": "There",
            "到处": "Everywhere", "某处": "Somewhere",
            "电脑": "Computer", "手机": "Phone",
            "书": "Book", "笔": "Pen", "纸": "Paper",
            "桌子": "Table", "椅子": "Chair", "床": "Bed",
            "门": "Door", "窗": "Window", "墙": "Wall",
            "衣服": "Clothes", "鞋子": "Shoes", "帽子": "Hat",
            "钱包": "Wallet", "钥匙": "Key", "包": "Bag",
            "钱": "Money", "卡": "Card", "票": "Ticket",
            "地图": "Map", "照片": "Photo", "电话": "Telephone",
            "电视": "TV", "音乐": "Music", "电影": "Movie",
            "游戏": "Game", "体育": "Sports", "运动": "Exercise",
            "学习": "Study", "工作": "Work", "生活": "Life",
            "世界": "World", "地球": "Earth", "太阳": "Sun",
            "月亮": "Moon", "星星": "Star", "天空": "Sky",
            "云": "Cloud", "雨": "Rain", "雪": "Snow",
            "风": "Wind", "天气": "Weather",
            "温度": "Temperature", "度": "Degree",
            "こんにちは": "你好", "こんばんは": "晚上好",
            "おはよう": "早上好", "おやすみ": "晚安",
            "ありがとう": "谢谢", "すみません": "对不起",
            "ごめんなさい": "对不起", "さようなら": "再见",
            "はい": "是的", "いいえ": "不是",
            "わかりました": "明白了", "わかりません": "不明白",
            "お願いします": "拜托了", "いただきます": "我开动了",
            "ごちそうさま": "多谢款待", "大丈夫": "没关系",
            "すごい": "厉害", "かわいい": "可爱",
            "きれい": "漂亮", "美味しい": "好吃",
            "楽しい": "开心", "嬉しい": "高兴",
            "悲しい": "悲伤", "難しい": "难",
            "簡単": "简单", "新しい": "新的",
            "古い": "旧的", "大きい": "大的",
            "小さい": "小的", "熱い": "热的",
            "冷たい": "冷的", "高い": "高的/贵的",
            "安い": "便宜的", "遠い": "远的",
            "近い": "近的", "早い": "快的/早的",
            "遅い": "慢的/晚的",
            "안녕하세요": "你好", "안녕히 가세요": "再见",
            "감사합니다": "谢谢", "고맙습니다": "谢谢",
            "죄송합니다": "对不起", "미안합니다": "对不起",
            "괜찮아요": "没关系", "네": "是的",
            "아니요": "不是", "좋아요": "好的",
            "맛있어요": "好吃", "예뻐요": "漂亮",
            "멋져요": "帅气", "재미있어요": "有趣",
            "어려워요": "难", "쉬워요": "简单",
            "빨라요": "快", "느려요": "慢",
            "커요": "大", "작아요": "小",
            "비싸요": "贵", "싸요": "便宜",
            "bonjour": "你好/早上好", "bonsoir": "晚上好",
            "bonne nuit": "晚安", "au revoir": "再见",
            "merci": "谢谢", "merci beaucoup": "非常感谢",
            "pardon": "对不起", "excusez-moi": "打扰一下",
            "s'il vous plaît": "请", "oui": "是的",
            "non": "不是", "d'accord": "好的",
            "je t'aime": "我爱你", "très bien": "非常好",
            "beau": "漂亮", "bon": "好",
            "mauvais": "坏", "grand": "大",
            "petit": "小", "chaud": "热",
            "froid": "冷", "vite": "快",
            "lent": "慢", "cher": "贵",
            "bon marché": "便宜",
            "hallo": "你好", "guten Morgen": "早上好",
            "guten Abend": "晚上好", "gute Nacht": "晚安",
            "tschüss": "再见", "auf Wiedersehen": "再见",
            "danke": "谢谢", "vielen Dank": "非常感谢",
            "bitte": "请/不客气", "entschuldigung": "对不起",
            "ja": "是的", "nein": "不是",
            "gut": "好", "schlecht": "坏",
            "groß": "大", "klein": "小",
            "heiß": "热", "kalt": "冷",
            "schnell": "快", "langsam": "慢",
            "teuer": "贵", "billig": "便宜",
            "ich liebe dich": "我爱你",
            "alles Gute": "一切顺利",
            "hola": "你好", "buenos días": "早上好",
            "buenas tardes": "下午好", "buenas noches": "晚上好",
            "adiós": "再见", "hasta luego": "回头见",
            "gracias": "谢谢", "muchas gracias": "非常感谢",
            "lo siento": "对不起", "perdón": "对不起",
            "por favor": "请", "sí": "是的",
            "no": "不是", "bueno": "好",
            "malo": "坏", "grande": "大",
            "pequeño": "小", "caliente": "热",
            "frío": "冷", "rápido": "快",
            "lento": "慢", "caro": "贵",
            "barato": "便宜", "te quiero": "我爱你",
            "muy bien": "非常好", "de nada": "不客气",
            
            # === 俄语基础 ===
            "здравствуйте": "你好", "привет": "嗨",
            "до свидания": "再见", "пока": "拜拜",
            "спасибо": "谢谢", "большое спасибо": "非常感谢",
            "извините": "对不起", "простите": "请原谅",
            "пожалуйста": "请/不客气", "да": "是的",
            "нет": "不是", "хорошо": "好",
            "плохо": "坏", "большой": "大",
            "маленький": "小", "горячий": "热",
            "холодный": "冷", "быстрый": "快",
            "медленный": "慢", "дорогой": "贵",
            "дешёвый": "便宜", "я люблю тебя": "我爱你",
        }
        self.words = self.load_dictionary()

    def get_dict_count(self):
        return len(self.words)

    def load_dictionary(self):
        word_dict = self.default_words.copy()
        if os.path.exists(DICT_FILE):
            try:
                with open(DICT_FILE, "r", encoding="utf-8") as f:
                    user_dict = json.load(f)
                    word_dict.update(user_dict)
            except:
                pass
        return word_dict

    def save_dictionary(self):
        # 只保存用户新增词条，系统内置词条不写入文件
        user_data = {}
        for k, v in self.words.items():
            if k not in self.default_words:
                user_data[k] = v
        try:
            with open(DICT_FILE, "w", encoding="utf-8") as f:
                json.dump(user_data, f, ensure_ascii=False, indent=2)
        except:
            pass

    def add_word(self, source, target):
        self.words[source] = target
        self.save_dictionary()

    # 新增：删除单个词条
    def delete_word(self, source_key):
        if source_key in self.words:
            # 禁止删除系统自带词条
            if source_key in self.default_words:
                return False, "该词条为系统内置词条，无法删除"
            del self.words[source_key]
            self.save_dictionary()
            return True, "删除成功"
        return False, "未找到该词条"

    # 新增：清空所有用户自定义词条
    def clear_user_words(self):
        del_keys = [k for k in self.words if k not in self.default_words]
        for k in del_keys:
            del self.words[k]
        self.save_dictionary()

    def translate(self, text, source_lang, target_lang):
        text_raw = text.strip()
        if not text_raw:
            return ""
        if text_raw in self.words:
            return self.words[text_raw]
        text_low = text_raw.lower()
        if text_low in self.words:
            return self.words[text_low]
        if re.search(r'[\u4e00-\u9fff]', text_raw):
            for word in list(self.words.keys()):
                if re.search(r'[\u4e00-\u9fff]', word) and word in text_raw:
                    text_raw = text_raw.replace(word, self.words[word])
            if text_raw != text.strip():
                return text_raw
        if re.match(r'^[a-zA-Z\s\.,!? ]+$', text_raw):
            word_list = re.split(r'([\s,.!?])', text_raw)
            output_list = []
            for seg in word_list:
                seg_low = seg.strip(".,!?").lower()
                output_list.append(self.words.get(seg_low, seg))
            final_text = "".join(output_list)
            if final_text != text_raw:
                return final_text
        return f"[未找到翻译]\n{text.strip()}"

    def detect_language(self, text):
        if not text.strip(): return "en"
        zh_cnt = len(re.findall(r'[\u4e00-\u9fff]', text))
        ja_cnt = len(re.findall(r'[\u3040-\u30ff]', text))
        ko_cnt = len(re.findall(r'[\uac00-\ud7af]', text))
        total = len(text.strip())
        if zh_cnt / total > 0.3: return "zh"
        if ja_cnt / total > 0.3: return "ja"
        if ko_cnt / total > 0.3: return "ko"
        return "en"

# ==================== 翻译管理器 ====================
class Translator:
    def __init__(self, config):
        self.engines = {}
        self.current = None
        self.history = []
        self.config = config
        self.register("在线翻译", OnlineTranslator())
        self.register("本地词典", LocalTranslator())
        default_engine = self.config.get("default_engine", "在线翻译")
        self.current = self.engines.get(default_engine, self.engines["在线翻译"])
        self.load_history()

    def register(self, name, engine):
        self.engines[name] = engine

    def set_engine(self, name):
        if name in self.engines:
            self.current = self.engines[name]
            return True
        return False

    def get_engine_names(self):
        return list(self.engines.keys())

    def get_local_dict_obj(self):
        return self.engines["本地词典"]

    def translate(self, text, src_lang, dst_lang):
        result = self.current.translate(text, src_lang, dst_lang)
        self.history.insert(0, {
            "source": text, "target": result,
            "source_lang": src_lang, "target_lang": dst_lang,
            "engine": self.current.name, "time": datetime.now().isoformat()
        })
        if len(self.history) > 100:
            self.history.pop()
        self.save_history()
        return result

    def detect_language(self, text):
        return self.current.detect_language(text) if self.current else "en"

    def load_history(self):
        if os.path.exists(HISTORY_FILE):
            try:
                with open(HISTORY_FILE, "r", encoding="utf-8") as f:
                    self.history = json.load(f)
            except:
                self.history = []

    def save_history(self):
        try:
            with open(HISTORY_FILE, "w", encoding="utf-8") as f:
                json.dump(self.history, f, ensure_ascii=False, indent=2)
        except:
            pass

    def clear_history(self):
        self.history.clear()
        self.save_history()

# ==================== 主界面窗口 ====================
class App:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title(APP_NAME)
        self.root.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}")
        self.root.minsize(650, 520)
        self.config = self.load_config()
        self.translator = Translator(self.config)
        self.msg_queue = queue.Queue()
        self.build_ui()
        self.bind_event()
        self.handle_queue()
        self.refresh_dict_num()

    def refresh_dict_num(self):
        dict_obj = self.translator.get_local_dict_obj()
        count = dict_obj.get_dict_count()
        self.dict_num_label.config(
            text=f"📚 词典总词条：{count} 条",
            font=("微软雅黑", 10, "bold"),
            foreground="#008822"
        )

    def load_config(self):
        default_cfg = {"default_engine": "在线翻译", "auto_detect": True, "font_size": 11}
        if os.path.exists(CONFIG_FILE):
            try:
                with open(CONFIG_FILE, "r", encoding="utf-8") as f:
                    default_cfg.update(json.load(f))
            except:
                pass
        return default_cfg

    def save_config(self):
        try:
            with open(CONFIG_FILE, "w", encoding="utf-8") as f:
                json.dump(self.config, f, ensure_ascii=False, indent=2)
        except:
            pass

    def build_ui(self):
        menu_bar = tk.Menu(self.root)
        self.root.config(menu=menu_bar)
        file_menu = tk.Menu(menu_bar, tearoff=0)
        menu_bar.add_cascade(label="文件", menu=file_menu)
        file_menu.add_command(label="导入文本(Ctrl+O)", command=self.import_txt)
        file_menu.add_command(label="导出结果(Ctrl+S)", command=self.export_txt)
        file_menu.add_separator()
        file_menu.add_command(label="退出(Ctrl+Q)", command=self.exit_app)

        tool_menu = tk.Menu(menu_bar, tearoff=0)
        menu_bar.add_cascade(label="工具", menu=tool_menu)
        tool_menu.add_command(label="词典管理", command=self.open_dict_win)
        tool_menu.add_command(label="历史记录", command=self.open_history_win)

        help_menu = tk.Menu(menu_bar, tearoff=0)
        menu_bar.add_cascade(label="帮助", menu=help_menu)
        help_menu.add_command(label="使用说明", command=self.show_help_info)
        help_menu.add_command(label="关于软件", command=self.show_about_info)

        main_frame = ttk.Frame(self.root, padding=10)
        main_frame.pack(fill="both", expand=True)

        ctrl_frame = ttk.Frame(main_frame)
        ctrl_frame.pack(fill="x", pady=(0, 10))
        ttk.Label(ctrl_frame, text="源语言:").pack(side="left")
        self.src_box = ttk.Combobox(ctrl_frame, values=list(LANGUAGES.keys()), state="readonly", width=12)
        self.src_box.pack(side="left", padx=4)
        self.src_box.set("自动检测")
        ttk.Button(ctrl_frame, text="⇄", command=self.swap_language, width=3).pack(side="left", padx=4)
        ttk.Label(ctrl_frame, text="目标语言:").pack(side="left")
        self.dst_box = ttk.Combobox(ctrl_frame, values=list(LANGUAGES.keys()), state="readonly", width=12)
        self.dst_box.pack(side="left", padx=4)
        self.dst_box.set("英语")
        ttk.Label(ctrl_frame, text="翻译引擎:").pack(side="left", padx=(12, 4))
        self.engine_box = ttk.Combobox(ctrl_frame, values=self.translator.get_engine_names(), state="readonly", width=10)
        self.engine_box.pack(side="left")
        self.engine_box.set(self.translator.current.name)
        self.engine_box.bind("<<ComboboxSelected>>", self.change_engine)
        self.auto_check = tk.BooleanVar(value=self.config["auto_detect"])
        ttk.Checkbutton(ctrl_frame, text="自动识别语种", variable=self.auto_check, command=self.save_config).pack(side="left", padx=8)
        self.dict_num_label = ttk.Label(ctrl_frame, text="", foreground="#227722")
        self.dict_num_label.pack(side="right")

        input_group = ttk.LabelFrame(main_frame, text="输入待翻译文本", padding=5)
        input_group.pack(fill="both", expand=True, pady=(0, 5))
        self.input_area = scrolledtext.ScrolledText(input_group, wrap="word", font=("Microsoft YaHei", self.config["font_size"]), height=7)
        self.input_area.pack(fill="both", expand=True)
        input_bottom = ttk.Frame(input_group)
        input_bottom.pack(fill="x", pady=(4, 0))
        self.input_char = ttk.Label(input_bottom, text="字符数：0")
        self.input_char.pack(side="left")
        ttk.Button(input_bottom, text="清空", command=self.clear_input).pack(side="right")

        btn_bar = ttk.Frame(main_frame)
        btn_bar.pack(fill="x", pady=4)
        self.translate_btn = ttk.Button(btn_bar, text="开始翻译(Enter)", command=self.run_translate, width=14)
        self.translate_btn.pack(side="left", padx=5)
        self.load_bar = ttk.Progressbar(btn_bar, mode="indeterminate", length=110)
        self.load_bar.pack(side="left", padx=8)
        self.load_bar.pack_forget()
        self.state_text = ttk.Label(btn_bar, text="就绪", foreground="#555555")
        self.state_text.pack(side="left", padx=8)

        output_group = ttk.LabelFrame(main_frame, text="翻译结果", padding=5)
        output_group.pack(fill="both", expand=True, pady=(5, 0))
        self.output_area = scrolledtext.ScrolledText(output_group, wrap="word", font=("Microsoft YaHei", self.config["font_size"]), bg="#f8f8f8", height=7)
        self.output_area.pack(fill="both", expand=True)
        output_bottom = ttk.Frame(output_group)
        output_bottom.pack(fill="x", pady=(4, 0))
        self.output_char = ttk.Label(output_bottom, text="字符数：0")
        self.output_char.pack(side="left")
        ttk.Button(output_bottom, text="复制结果", command=self.copy_result).pack(side="right", padx=3)
        ttk.Button(output_bottom, text="清空", command=self.clear_output).pack(side="right")

        self.status_bar = ttk.Label(main_frame, text=f"{APP_NAME} | 运行就绪", relief="sunken", anchor="w", padding=(6, 3))
        self.status_bar.pack(fill="x", pady=(6, 0))

    def bind_event(self):
        self.root.bind("<Return>", lambda e: self.run_translate())
        self.root.bind("<Control-o>", lambda e: self.import_txt())
        self.root.bind("<Control-s>", lambda e: self.export_txt())
        self.root.bind("<Control-q>", lambda e: self.exit_app())
        self.input_area.bind("<KeyRelease>", self.count_input_text)
        self.root.protocol("WM_DELETE_WINDOW", self.exit_app)

    def change_engine(self, event):
        eng_name = self.engine_box.get()
        if self.translator.set_engine(eng_name):
            self.config["default_engine"] = eng_name
            self.save_config()
            self.state_text.config(text=f"已切换引擎：{eng_name}")
            self.status_bar.config(text=f"{APP_NAME} | 当前引擎：{eng_name}")

    def swap_language(self):
        src_val = self.src_box.get()
        dst_val = self.dst_box.get()
        if src_val == "自动检测":
            messagebox.showinfo("提示", "自动检测模式无法互换语种")
            return
        self.src_box.set(dst_val)
        self.dst_box.set(src_val)

    def count_input_text(self, event=None):
        txt = self.input_area.get("1.0", tk.END).strip()
        self.input_char.config(text=f"字符数：{len(txt)}")

    def run_translate(self):
        content = self.input_area.get("1.0", tk.END).strip()
        if not content:
            messagebox.showwarning("提醒", "请填写需要翻译的文本")
            return
        src_name = self.src_box.get()
        dst_name = self.dst_box.get()
        src_code = LANGUAGES[src_name]
        dst_code = LANGUAGES[dst_name]
        if self.auto_check.get() and src_code == "auto":
            detect_code = self.translator.detect_language(content)
            for name, code in LANGUAGES.items():
                if code == detect_code:
                    self.src_box.set(name)
                    break
        self.translate_btn.config(state="disabled")
        self.load_bar.pack(side="left", padx=8)
        self.load_bar.start(12)
        self.state_text.config(text="正在翻译...")
        work_thread = threading.Thread(target=self.translate_task, args=(content, src_code, dst_code), daemon=True)
        work_thread.start()

    def translate_task(self, txt, src, dst):
        try:
            res = self.translator.translate(txt, src, dst)
            self.msg_queue.put(("ok", res))
        except Exception as err:
            self.msg_queue.put(("error", str(err)))

    def handle_queue(self):
        try:
            while True:
                msg_type, data = self.msg_queue.get_nowait()
                self.load_bar.stop()
                self.load_bar.pack_forget()
                self.translate_btn.config(state="normal")
                if msg_type == "ok":
                    self.output_area.delete("1.0", tk.END)
                    self.output_area.insert("1.0", data)
                    self.output_char.config(text=f"字符数：{len(data)}")
                    self.state_text.config(text="翻译完成 ✓")
                else:
                    self.output_area.delete("1.0", tk.END)
                    self.output_area.insert("1.0", f"翻译异常：{data}")
                    self.state_text.config(text="翻译失败")
        except queue.Empty:
            pass
        self.root.after(100, self.handle_queue)

    def clear_input(self):
        self.input_area.delete("1.0", tk.END)
        self.input_char.config(text="字符数：0")

    def clear_output(self):
        self.output_area.delete("1.0", tk.END)
        self.output_char.config(text="字符数：0")

    def copy_result(self):
        res_txt = self.output_area.get("1.0", tk.END).strip()
        if res_txt:
            self.root.clipboard_clear()
            self.root.clipboard_append(res_txt)
            self.state_text.config(text="结果已复制剪贴板")

    def import_txt(self):
        path = filedialog.askopenfilename(filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")])
        if not path:
            return
        try:
            with open(path, "r", encoding="utf-8") as f:
                file_content = f.read()
            self.input_area.delete("1.0", tk.END)
            self.input_area.insert("1.0", file_content)
            self.count_input_text()
            self.state_text.config(text=f"导入文件：{os.path.basename(path)}")
        except Exception as e:
            messagebox.showerror("导入失败", str(e))

    def export_txt(self):
        res_data = self.output_area.get("1.0", tk.END).strip()
        if not res_data:
            messagebox.showwarning("提示", "暂无翻译结果可导出")
            return
        save_path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("TXT文档", "*.txt")])
        if not save_path:
            return
        try:
            with open(save_path, "w", encoding="utf-8") as f:
                f.write(res_data)
            self.state_text.config(text="文件导出成功")
        except Exception as e:
            messagebox.showerror("导出失败", str(e))

    def open_dict_win(self):
        DictManageWindow(self.root, self.translator, self.refresh_dict_num)

    def open_history_win(self):
        HistoryViewWindow(self.root, self.translator)

    def show_help_info(self):
        help_info = """软件使用说明
1、输入文本，选择源语言、目标语言，点击翻译或回车执行
2、在线翻译：多接口备用，联网即可使用；本地词典：离线双向中英翻译
3、快捷键
Enter：翻译 ｜ Ctrl+O：导入txt ｜ Ctrl+S：导出结果 ｜ Ctrl+Q：退出
4、词典管理可查看全部词条、添加/删除自定义单词，系统内置词条无法删除
"""
        win = tk.Toplevel(self.root)
        win.title("使用帮助")
        win.geometry("420x280")
        text_box = scrolledtext.ScrolledText(win, font=("微软雅黑", 10))
        text_box.pack(fill="both", expand=True, padx=10, pady=10)
        text_box.insert("1.0", help_info)
        text_box.config(state="disabled")

    def show_about_info(self):
        dict_count = self.translator.get_local_dict_obj().get_dict_count()
        messagebox.showinfo("关于", f"{APP_NAME}\n本地真实词条数量：{dict_count} 条\n支持中英离线双向翻译")

    def exit_app(self):
        self.save_config()
        self.root.destroy()

    def run_app(self):
        self.root.mainloop()

# ==================== 词典管理窗口【增加删除词条】 ====================
class DictManageWindow:
    def __init__(self, parent, translator, refresh_callback):
        self.win = tk.Toplevel(parent)
        self.win.title("词典管理 - 查看&添加&删除词条")
        self.win.geometry("560x480")
        self.trans = translator
        self.refresh_cb = refresh_callback
        self.local_dict = translator.get_local_dict_obj()
        self.build_dict_ui()
        self.refresh_dict_view()

    def show_current_count(self):
        cnt = self.local_dict.get_dict_count()
        self.count_label.config(text=f"📖 当前词典总条目：{cnt} 条", font=("微软雅黑",10,"bold"), foreground="#007722")

    def build_dict_ui(self):
        main_frame = ttk.Frame(self.win, padding=10)
        main_frame.pack(fill="both", expand=True)
        self.count_label = ttk.Label(main_frame, text="")
        self.count_label.pack(anchor="w", pady=(0,8))

        # 新增词条区域
        add_frame = ttk.LabelFrame(main_frame, text="新增词条", padding=8)
        add_frame.pack(fill="x", pady=(0,10))
        ttk.Label(add_frame, text="原文：", width=6).grid(row=0, column=0, sticky="w")
        self.src_entry = ttk.Entry(add_frame, width=30)
        self.src_entry.grid(row=0, column=1, padx=8)
        ttk.Label(add_frame, text="译文：", width=6).grid(row=1, column=0, sticky="w", pady=6)
        self.dst_entry = ttk.Entry(add_frame, width=30)
        self.dst_entry.grid(row=1, column=1, padx=8)
        btn_frame1 = ttk.Frame(add_frame)
        btn_frame1.grid(row=0, column=2, rowspan=2, padx=10)
        ttk.Button(btn_frame1, text="添加词条", command=self.add_word_item).pack(pady=2)

        # 删除词条区域
        del_frame = ttk.LabelFrame(main_frame, text="删除自定义词条（系统内置词条不可删）", padding=8)
        del_frame.pack(fill="x", pady=(0,10))
        ttk.Label(del_frame, text="待删原文：", width=8).grid(row=0, column=0, sticky="w")
        self.del_entry = ttk.Entry(del_frame, width=35)
        self.del_entry.grid(row=0, column=1, padx=8)
        ttk.Button(del_frame, text="删除本条", command=self.delete_single_word).grid(row=0, column=2, padx=5)
        ttk.Button(del_frame, text="清空所有自定义词条", command=self.clear_all_custom_word, style="Danger.TButton").grid(row=1, column=1, pady=6)

        # 词条列表
        list_frame = ttk.LabelFrame(main_frame, text="全部词典词条（原文 ↔ 译文）", padding=5)
        list_frame.pack(fill="both", expand=True)
        self.dict_text = scrolledtext.ScrolledText(list_frame, font=("Consolas",9), bg="#fdfdfd")
        self.dict_text.pack(fill="both", expand=True)

        bottom_btn = ttk.Frame(main_frame)
        bottom_btn.pack(fill="x", pady=(8,0))
        ttk.Button(bottom_btn, text="刷新列表", command=self.refresh_dict_view).pack(side="left")
        ttk.Button(bottom_btn, text="关闭窗口", command=self.win.destroy).pack(side="right")

    def refresh_dict_view(self):
        self.dict_text.config(state=tk.NORMAL)
        self.dict_text.delete("1.0", tk.END)
        data = self.local_dict.words.items()
        line = 1
        self.dict_text.insert(tk.END, f"{'序号':<4}{'原文':<22}{'译文'}\n" + "-"*50 + "\n")
        for k, v in sorted(data):
            # 区分系统自带 / 用户自定义词条
            tag = "【系统】" if k in self.local_dict.default_words else "【自定义】"
            self.dict_text.insert(tk.END, f"{line:<4}{k:<22}{tag} {v}\n")
            line += 1
        self.dict_text.config(state=tk.DISABLED)
        self.show_current_count()

    def add_word_item(self):
        s = self.src_entry.get().strip()
        d = self.dst_entry.get().strip()
        if not s or not d:
            messagebox.showwarning("提示", "原文和译文不能为空")
            return
        self.local_dict.add_word(s, d)
        messagebox.showinfo("成功", "词条添加完成")
        self.src_entry.delete(0, tk.END)
        self.dst_entry.delete(0, tk.END)
        self.refresh_dict_view()
        self.refresh_cb()

    # 删除单个词条
    def delete_single_word(self):
        key = self.del_entry.get().strip()
        if not key:
            messagebox.showwarning("提示", "请输入要删除的原文内容")
            return
        ok, msg = self.local_dict.delete_word(key)
        if ok:
            messagebox.showinfo("成功", msg)
            self.del_entry.delete(0, tk.END)
        else:
            messagebox.showerror("失败", msg)
        self.refresh_dict_view()
        self.refresh_cb()

    # 清空全部自定义词条
    def clear_all_custom_word(self):
        if messagebox.askyesno("确认操作", "确定清空所有你自己添加的词条吗？系统词条不会被删除，该操作不可恢复！"):
            self.local_dict.clear_user_words()
            messagebox.showinfo("完成", "所有自定义词条已清空")
            self.refresh_dict_view()
            self.refresh_cb()

# ==================== 历史记录弹窗 ====================
class HistoryViewWindow:
    def __init__(self, parent, translator):
        self.win = tk.Toplevel(parent)
        self.win.title("翻译历史记录")
        self.win.geometry("600x380")
        self.trans = translator
        self.build_history_ui()

    def build_history_ui(self):
        frame = ttk.Frame(self.win, padding=10)
        frame.pack(fill="both", expand=True)
        text_area = scrolledtext.ScrolledText(frame, font=("微软雅黑", 10))
        text_area.pack(fill="both", expand=True)
        data = self.trans.history
        if not data:
            text_area.insert("1.0", "暂无翻译历史记录")
        else:
            for idx, item in enumerate(data, 1):
                txt = f"【{idx}】 时间：{item['time'][:19]}\n原文：{item['source']}\n译文：{item['target']}\n引擎：{item['engine']}\n-----------------------------\n"
                text_area.insert(tk.END, txt)
        text_area.config(state="disabled")
        btn_frame = ttk.Frame(frame)
        btn_frame.pack(fill="x", pady=(6, 0))
        ttk.Button(btn_frame, text="清空全部记录", command=self.clear_all_history).pack(side="left")
        ttk.Button(btn_frame, text="关闭", command=self.win.destroy).pack(side="right")

    def clear_all_history(self):
        if messagebox.askyesno("确认", "确定清空所有历史记录吗？"):
            self.trans.clear_history()
            messagebox.showinfo("完成", "历史记录已清空")
            self.win.destroy()

# 程序入口
if __name__ == "__main__":
    app = App()
    app.run_app()