import json
import random
import os
from datetime import datetime
import tkinter as tk
from tkinter import ttk, messagebox, filedialog, scrolledtext
import tkinter.simpledialog as tk_simpledialog
tk.simpledialog = tk_simpledialog

class WordMemorizer:
    def __init__(self, word_file="words.json", log_file="study_log.json"):
        self.word_file = word_file
        self.log_file = log_file
        self.words = []
        self.error_words = []
        self.daily_target = 20
        self.load_words()
        self.load_study_log()

    def load_words(self):
        if os.path.exists(self.word_file):
            with open(self.word_file, 'r', encoding='utf-8') as f:
                data = json.load(f)
                self.words = data.get('words', [])
        else:
            # 扩充大量基础英语单词
            self.words = [
                {"word": "apple", "meaning": "苹果", "mastery": 0},
                {"word": "book", "meaning": "书", "mastery": 0},
                {"word": "cat", "meaning": "猫", "mastery": 0},
                {"word": "dog", "meaning": "狗", "mastery": 0},
                {"word": "elephant", "meaning": "大象", "mastery": 0},
                {"word": "banana", "meaning": "香蕉", "mastery": 0},
                {"word": "orange", "meaning": "橙子", "mastery": 0},
                {"word": "pear", "meaning": "梨", "mastery": 0},
                {"word": "watermelon", "meaning": "西瓜", "mastery": 0},
                {"word": "grape", "meaning": "葡萄", "mastery": 0},
                {"word": "pen", "meaning": "钢笔", "mastery": 0},
                {"word": "pencil", "meaning": "铅笔", "mastery": 0},
                {"word": "ruler", "meaning": "尺子", "mastery": 0},
                {"word": "eraser", "meaning": "橡皮", "mastery": 0},
                {"word": "schoolbag", "meaning": "书包", "mastery": 0},
                {"word": "bird", "meaning": "小鸟", "mastery": 0},
                {"word": "fish", "meaning": "鱼", "mastery": 0},
                {"word": "tiger", "meaning": "老虎", "mastery": 0},
                {"word": "lion", "meaning": "狮子", "mastery": 0},
                {"word": "rabbit", "meaning": "兔子", "mastery": 0},
                {"word": "mother", "meaning": "妈妈", "mastery": 0},
                {"word": "father", "meaning": "爸爸", "mastery": 0},
                {"word": "sister", "meaning": "姐妹", "mastery": 0},
                {"word": "brother", "meaning": "兄弟", "mastery": 0},
                {"word": "grandma", "meaning": "奶奶；外婆", "mastery": 0},
                {"word": "grandpa", "meaning": "爷爷；外公", "mastery": 0},
                {"word": "red", "meaning": "红色", "mastery": 0},
                {"word": "blue", "meaning": "蓝色", "mastery": 0},
                {"word": "yellow", "meaning": "黄色", "mastery": 0},
                {"word": "green", "meaning": "绿色", "mastery": 0},
                {"word": "white", "meaning": "白色", "mastery": 0},
                {"word": "black", "meaning": "黑色", "mastery": 0},
                {"word": "morning", "meaning": "早上", "mastery": 0},
                {"word": "afternoon", "meaning": "下午", "mastery": 0},
                {"word": "evening", "meaning": "晚上", "mastery": 0},
                {"word": "today", "meaning": "今天", "mastery": 0},
                {"word": "tomorrow", "meaning": "明天", "mastery": 0},
                {"word": "yesterday", "meaning": "昨天", "mastery": 0},
                {"word": "happy", "meaning": "开心的", "mastery": 0},
                {"word": "sad", "meaning": "伤心的", "mastery": 0},
                {"word": "tall", "meaning": "高的", "mastery": 0},
                {"word": "short", "meaning": "矮的；短的", "mastery": 0},
                {"word": "big", "meaning": "大的", "mastery": 0},
                {"word": "small", "meaning": "小的", "mastery": 0},
                {"word": "hot", "meaning": "热的", "mastery": 0},
                {"word": "cold", "meaning": "冷的", "mastery": 0},
                {"word": "run", "meaning": "跑", "mastery": 0},
                {"word": "jump", "meaning": "跳", "mastery": 0},
                {"word": "walk", "meaning": "走路", "mastery": 0},
                {"word": "eat", "meaning": "吃", "mastery": 0},
                {"word": "drink", "meaning": "喝", "mastery": 0},
                {"word": "sleep", "meaning": "睡觉", "mastery": 0},
                {"word": "read", "meaning": "阅读", "mastery": 0},
                {"word": "write", "meaning": "写", "mastery": 0},
                {"word": "dance", "meaning": "跳舞", "mastery": 0},
                {"word": "sing", "meaning": "唱歌", "mastery": 0},
                {"word": "water", "meaning": "水", "mastery": 0},
                {"word": "milk", "meaning": "牛奶", "mastery": 0},
                {"word": "rice", "meaning": "米饭", "mastery": 0},
                {"word": "egg", "meaning": "鸡蛋", "mastery": 0},
                {"word": "bread", "meaning": "面包", "mastery": 0},
                {"word": "cake", "meaning": "蛋糕", "mastery": 0},
                {"word": "house", "meaning": "房子", "mastery": 0},
                {"word": "door", "meaning": "门", "mastery": 0},
                {"word": "window", "meaning": "窗户", "mastery": 0},
                {"word": "table", "meaning": "桌子", "mastery": 0},
                {"word": "chair", "meaning": "椅子", "mastery": 0},
                {"word": "sun", "meaning": "太阳", "mastery": 0},
                {"word": "moon", "meaning": "月亮", "mastery": 0},
                {"word": "star", "meaning": "星星", "mastery": 0},
                {"word": "rain", "meaning": "雨", "mastery": 0},
                {"word": "wind", "meaning": "风", "mastery": 0}
            ]
            self.save_words()

    def save_words(self):
        with open(self.word_file, 'w', encoding='utf-8') as f:
            json.dump({"words": self.words}, f, ensure_ascii=False, indent=2)

    def load_study_log(self):
        if os.path.exists(self.log_file):
            with open(self.log_file, 'r', encoding='utf-8') as f:
                self.study_log = json.load(f)
        else:
            self.study_log = {"records": [], "daily_count": {}, "today": datetime.now().strftime("%Y-%m-%d")}
            self.save_log()

    def save_log(self):
        with open(self.log_file, 'w', encoding='utf-8') as f:
            json.dump(self.study_log, f, ensure_ascii=False, indent=2)

    def add_study_record(self, word, is_correct, mode):
        now = datetime.now()
        date_str = now.strftime("%Y-%m-%d")
        record = {
            "date": date_str,
            "time": now.strftime("%H:%M:%S"),
            "word": word["word"],
            "meaning": word["meaning"],
            "correct": is_correct,
            "mode": mode
        }
        self.study_log["records"].append(record)
        if date_str not in self.study_log["daily_count"]:
            self.study_log["daily_count"][date_str] = 0
        self.study_log["daily_count"][date_str] += 1
        self.save_log()

    def add_word(self, word, meaning):
        word_low = word.lower().strip()
        for w in self.words:
            if w['word'] == word_low:
                return False, "单词已存在"
        self.words.append({"word": word_low, "meaning": meaning.strip(), "mastery": 0})
        self.save_words()
        return True, "添加成功"

    def delete_word(self, word):
        word_low = word.lower().strip()
        for i, w in enumerate(self.words):
            if w['word'] == word_low:
                del self.words[i]
                self.save_words()
                return True, "删除成功"
        return False, "单词不存在"

    def reset_mastery(self, word):
        word_low = word.lower().strip()
        for w in self.words:
            if w["word"] == word_low:
                w["mastery"] = 0
                self.save_words()
                return True, "熟练度已重置"
        return False, "未找到该单词"

    def clear_all_words(self):
        self.words.clear()
        self.save_words()
        return True, "单词库已清空"

    def import_words_from_txt(self, filepath):
        count = 0
        try:
            with open(filepath, "r", encoding="utf-8") as f:
                lines = f.readlines()
            for line in lines:
                line = line.strip()
                if not line or "|" not in line:
                    continue
                wd, mean = line.split("|", 1)
                wd = wd.lower().strip()
                if not any(x["word"] == wd for x in self.words):
                    self.words.append({"word": wd, "meaning": mean.strip(), "mastery": 0})
                    count += 1
            self.save_words()
            return True, f"成功导入 {count} 个新单词"
        except Exception as e:
            return False, f"导入失败：{str(e)}"

    def export_words_to_txt(self, filepath):
        try:
            with open(filepath, "w", encoding="utf-8") as f:
                for item in self.words:
                    f.write(f"{item['word']}|{item['meaning']}\n")
            return True, f"导出完成：{filepath}"
        except Exception as e:
            return False, f"导出失败：{str(e)}"

    def get_random_word(self, difficulty='all'):
        if not self.words:
            return None
        available = self.words.copy()
        if difficulty == 'new':
            available = [w for w in self.words if w['mastery'] < 3]
        elif difficulty == 'review':
            available = [w for w in self.words if 0 < w['mastery'] < 3]
        elif difficulty == 'mastered':
            available = [w for w in self.words if w['mastery'] >= 3]
        if not available:
            available = self.words
        return random.choice(available)

class MemorizerGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("英语单词背诵助手 GUI版")
        self.root.geometry("920x650")
        self.app = WordMemorizer()
        self.current_word = None
        self.test_mode = ""
        self.difficulty = "all"
        self.build_ui()

    def build_ui(self):
        main_frame = ttk.Frame(self.root, padding=10)
        main_frame.pack(fill=tk.BOTH, expand=True)

        left_panel = ttk.LabelFrame(main_frame, text="功能菜单", padding=8)
        left_panel.pack(side=tk.LEFT, fill=tk.Y, padx=(0,10))

        btn_list = [
            ("英译中测试", self.start_en2cn),
            ("中译英测试", self.start_cn2en),
            ("选择题测试", self.start_choice),
            ("错题练习", self.error_test),
            ("连续刷题", self.continuous_dialog),
            ("复习模式", self.review_mode),
            ("添加单词", self.add_word_dialog),
            ("删除单词", self.delete_word_dialog),
            ("重置熟练度", self.reset_word_dialog),
            ("单词列表", self.show_wordlist),
            ("学习统计", self.show_stat),
            ("导入TXT", self.import_txt),
            ("导出TXT", self.export_txt),
            ("清空词库", self.clear_all),
        ]
        for txt, cmd in btn_list:
            ttk.Button(left_panel, text=txt, command=cmd, width=16).pack(pady=3)

        diff_frame = ttk.LabelFrame(left_panel, text="选题难度")
        diff_frame.pack(pady=8, fill=tk.X)
        self.diff_var = tk.StringVar(value="all")
        ttk.Radiobutton(diff_frame, text="全部", variable=self.diff_var, value="all", command=self.set_diff).pack(anchor="w")
        ttk.Radiobutton(diff_frame, text="新词", variable=self.diff_var, value="new", command=self.set_diff).pack(anchor="w")
        ttk.Radiobutton(diff_frame, text="复习", variable=self.diff_var, value="review", command=self.set_diff).pack(anchor="w")
        ttk.Radiobutton(diff_frame, text="已掌握", variable=self.diff_var, value="mastered", command=self.set_diff).pack(anchor="w")

        right_panel = ttk.LabelFrame(main_frame, text="答题区", padding=10)
        right_panel.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)

        self.question_label = ttk.Label(right_panel, text="欢迎使用单词背诵工具，请左侧选择功能", font=("微软雅黑",16))
        self.question_label.pack(pady=15)

        self.input_var = tk.StringVar()
        self.answer_entry = ttk.Entry(right_panel, textvariable=self.input_var, font=("微软雅黑",14), width=35)
        self.answer_entry.pack(pady=8)
        self.answer_entry.bind("<Return>", self.submit_answer)

        btn_frame = ttk.Frame(right_panel)
        btn_frame.pack(pady=6)
        ttk.Button(btn_frame, text="提交答案", command=self.submit_answer).grid(row=0,column=0,padx=4)
        ttk.Button(btn_frame, text="下一题", command=self.next_question).grid(row=0,column=1,padx=4)

        self.result_text = scrolledtext.ScrolledText(right_panel, height=12, font=("微软雅黑",11))
        self.result_text.pack(fill=tk.BOTH, expand=True, pady=(10,0))

    def set_diff(self):
        self.difficulty = self.diff_var.get()

    def clear_output(self):
        self.result_text.delete(1.0, tk.END)

    def print_msg(self, msg):
        self.result_text.insert(tk.END, msg+"\n")
        self.result_text.see(tk.END)

    def start_en2cn(self):
        self.test_mode = "en2cn"
        self.next_question()

    def start_cn2en(self):
        self.test_mode = "cn2en"
        self.next_question()

    def start_choice(self):
        self.test_mode = "choice"
        self.next_question()

    def error_test(self):
        if not self.app.error_words:
            messagebox.showinfo("提示", "暂无错题，先进行测试！")
            return
        self.test_mode = "error"
        self.next_question()

    def next_question(self):
        self.input_var.set("")
        self.clear_output()
        if self.test_mode == "error":
            if not self.app.error_words:
                messagebox.showinfo("完成", "错题已全部答对！")
                return
            self.current_word = random.choice(self.app.error_words)
            self.question_label.config(text=f"翻译单词：{self.current_word['word']}")
        elif self.test_mode == "en2cn":
            self.current_word = self.app.get_random_word(self.difficulty)
            if not self.current_word:
                messagebox.showwarning("空", "单词库为空！")
                return
            self.question_label.config(text=f"英译中：{self.current_word['word']}")
        elif self.test_mode == "cn2en":
            self.current_word = self.app.get_random_word(self.difficulty)
            if not self.current_word:
                messagebox.showwarning("空", "单词库为空！")
                return
            self.question_label.config(text=f"中译英：{self.current_word['meaning']}")
        elif self.test_mode == "choice":
            self.current_word = self.app.get_random_word(self.difficulty)
            if not self.current_word:
                messagebox.showwarning("空", "单词库为空！")
                return
            self.build_choice()

    def build_choice(self):
        cw = self.current_word
        options = [cw]
        others = [w for w in self.app.words if w != cw]
        if len(others)>=3:
            options.extend(random.sample(others,3))
        else:
            options.extend(others)
        random.shuffle(options)
        self.choice_list = options
        txt = f"【选择题】{cw['word']}\n"
        for idx,opt in enumerate(options,1):
            txt += f"{idx}. {opt['meaning']}\n"
        self.question_label.config(text=txt)

    def submit_answer(self, event=None):
        if not self.current_word:
            return
        user_ans = self.input_var.get().strip()
        word = self.current_word
        correct = False
        if self.test_mode == "en2cn":
            if user_ans == word["meaning"]:
                self.print_msg("✅ 回答正确！")
                word["mastery"] = min(word["mastery"]+1,5)
                correct=True
            else:
                self.print_msg(f"❌ 错误！正确答案：{word['meaning']}")
                word["mastery"] = max(word["mastery"]-1,0)
                if word not in self.app.error_words:
                    self.app.error_words.append(word)
            self.app.add_study_record(word, correct, "英译中")
        elif self.test_mode == "cn2en":
            if user_ans.lower() == word["word"]:
                self.print_msg("✅ 回答正确！")
                word["mastery"] = min(word["mastery"]+1,5)
                correct=True
            else:
                self.print_msg(f"❌ 错误！正确答案：{word['word']}")
                word["mastery"] = max(word["mastery"]-1,0)
                if word not in self.app.error_words:
                    self.app.error_words.append(word)
            self.app.add_study_record(word, correct, "中译英")
        elif self.test_mode == "choice":
            try:
                sel = int(user_ans)-1
                if 0<=sel<len(self.choice_list):
                    if self.choice_list[sel]==word:
                        self.print_msg("✅ 正确！")
                        word["mastery"] = min(word["mastery"]+1,5)
                        correct=True
                    else:
                        self.print_msg(f"❌ 错误，正确：{word['meaning']}")
                        word["mastery"] = max(word["mastery"]-1,0)
                        if word not in self.app.error_words:
                            self.app.error_words.append(word)
                else:
                    self.print_msg("选项编号无效")
            except:
                self.print_msg("请输入数字编号")
            self.app.add_study_record(word, correct, "选择题")
        elif self.test_mode == "error":
            if user_ans == word["meaning"]:
                self.print_msg("✅ 答对，移出错题！")
                self.app.error_words.remove(word)
                word["mastery"] = min(word["mastery"]+1,5)
            else:
                self.print_msg(f"❌ 错误，正确：{word['meaning']}")
                word["mastery"] = max(word["mastery"]-1,0)
        self.app.save_words()

    def add_word_dialog(self):
        win = tk.Toplevel(self.root)
        win.title("添加单词")
        win.geometry("320x160")
        ttk.Label(win,text="英文单词：").pack()
        e1 = ttk.Entry(win)
        e1.pack()
        ttk.Label(win,text="中文释义：").pack()
        e2 = ttk.Entry(win)
        e2.pack()
        def submit():
            ok,msg = self.app.add_word(e1.get(),e2.get())
            messagebox.showinfo("结果",msg)
            win.destroy()
        ttk.Button(win,text="确认添加",command=submit).pack(pady=8)

    def delete_word_dialog(self):
        wd = tk.simpledialog.askstring("删除单词","输入要删除的英文单词")
        if not wd:
            return
        ok,msg = self.app.delete_word(wd)
        messagebox.showinfo("结果",msg)

    def reset_word_dialog(self):
        wd = tk.simpledialog.askstring("重置熟练度","输入单词")
        if not wd:
            return
        ok,msg = self.app.reset_mastery(wd)
        messagebox.showinfo("结果",msg)

    def show_wordlist(self):
        win = tk.Toplevel(self.root)
        win.title("单词列表")
        win.geometry("600x420")
        st = scrolledtext.ScrolledText(win,font=("微软雅黑",11))
        st.pack(fill=tk.BOTH,expand=True,padx=5,pady=5)
        if not self.app.words:
            st.insert(tk.END,"单词库为空")
        else:
            for i,w in enumerate(self.app.words,1):
                star = "★"*w["mastery"] + "☆"*(5-w["mastery"])
                st.insert(tk.END,f"{i}. {w['word']:<15} {w['meaning']:<12} [{star}]\n")
        st.config(state="disabled")

    def show_stat(self):
        total = len(self.app.words)
        mastered = sum(1 for w in self.app.words if w["mastery"]>=3)
        learning = total - mastered
        today = datetime.now().strftime("%Y-%m-%d")
        today_cnt = self.app.study_log["daily_count"].get(today,0)
        info = f"====学习统计====\n总单词：{total}\n已掌握：{mastered}\n学习中：{learning}\n今日刷题：{today_cnt}\n"
        messagebox.showinfo("统计信息", info)

    def import_txt(self):
        path = filedialog.askopenfilename(filetypes=[("文本文件","*.txt")])
        if not path:
            return
        ok,msg = self.app.import_words_from_txt(path)
        messagebox.showinfo("导入结果",msg)

    def export_txt(self):
        path = filedialog.asksaveasfilename(defaultextension=".txt",filetypes=[("文本文件","*.txt")])
        if not path:
            return
        ok,msg = self.app.export_words_to_txt(path)
        messagebox.showinfo("导出结果",msg)

    def clear_all(self):
        if messagebox.askyesno("确认","确定清空全部单词？不可恢复！"):
            self.app.clear_all_words()
            messagebox.showinfo("完成","单词库已清空")

    def continuous_dialog(self):
        msg = "1=英译中  2=中译英  3=选择题\n输入刷题数量与类型，逗号分隔\n例：10,1"
        res = tk.simpledialog.askstring("连续刷题",msg)
        if not res:
            return
        try:
            cnt,typ = res.split(",")
            cnt=int(cnt.strip())
            typ=int(typ.strip())
        except:
            messagebox.showerror("错误","格式错误")
            return
        if cnt<=0 or typ not in (1,2,3):
            return
        self.test_mode = {1:"en2cn",2:"cn2en",3:"choice"}[typ]
        self.clear_output()
        self.print_msg(f"开始连续 {cnt} 题")
        self.continuous_remain = cnt
        self.next_question()

    def review_mode(self):
        review_words = [w for w in self.app.words if 0<w["mastery"]<3]
        if not review_words:
            messagebox.showinfo("提示","暂无需要复习单词")
            return
        random.shuffle(review_words)
        win = tk.Toplevel(self.root)
        win.title("复习模式")
        win.geometry("400x200")
        idx_var = tk.IntVar(value=0)
        lb = ttk.Label(win,text="",font=("微软雅黑",15))
        lb.pack(pady=12)
        ans_var = tk.StringVar()
        ttk.Entry(win,textvariable=ans_var,font=("微软雅黑",12)).pack()
        def refresh():
            i = idx_var.get()
            if i>=len(review_words):
                lb.config(text="复习完成！")
                return
            w = review_words[i]
            lb.config(text=f"{w['word']}")
        def check():
            i = idx_var.get()
            if i>=len(review_words):
                return
            w = review_words[i]
            if ans_var.get().strip() == w["meaning"]:
                w["mastery"]=min(w["mastery"]+1,5)
            else:
                w["mastery"]=max(w["mastery"]-1,0)
            idx_var.set(i+1)
            ans_var.set("")
            refresh()
            self.app.save_words()
        ttk.Button(win,text="确认",command=check).pack(pady=6)
        refresh()

if __name__ == "__main__":
    root = tk.Tk()
    app = MemorizerGUI(root)
    root.mainloop()