import tkinter as tk
from tkinter import messagebox
import random
import time
import threading
import os
import json

DATA_FILE = "math_highscore.json"

class MentalMathApp:
    def __init__(self, root):
        self.root = root
        self.root.title("044. 口算训练器（限时版）")
        self.root.geometry("560x520")
        self.root.resizable(False, False)

        self.score = 0
        self.total = 0
        self.running = False
        self.current_answer = 0
        self.high_score = 0

        self.load_high_score()
        self.build_ui()

    # ========== 数据持久化 ==========
    def load_high_score(self):
        if os.path.exists(DATA_FILE):
            try:
                with open(DATA_FILE, "r", encoding="utf-8") as f:
                    data = json.load(f)
                    self.high_score = data.get("high_score", 0)
            except:
                self.high_score = 0
        else:
            self.high_score = 0

    def save_high_score(self):
        with open(DATA_FILE, "w", encoding="utf-8") as f:
            json.dump({"high_score": self.high_score}, f)

    # ========== UI 构建 ==========
    def build_ui(self):
        # 标题
        tk.Label(
            self.root, text="✏️ 口算训练器（限时版）",
            font=("微软雅黑", 18, "bold")
        ).pack(pady=10)

        # ===== 顶部信息栏 =====
        top_bar = tk.Frame(self.root)
        top_bar.pack(padx=20, pady=5, fill=tk.X)

        # ✅ 第 67 行：不使用 f-string（安全）
        self.timer_label = tk.Label(
            top_bar, text="⏱️ 准备就绪",
            font=("Consolas", 12, "bold"), fg="#E53935"
        )
        self.timer_label.pack(side=tk.LEFT)

        # ✅ 第 71 行：已修复（字符串拼接，兼容老 Python）
        self.hs_label = tk.Label(
            top_bar,
            text="最高分：" + str(self.high_score),
            font=("微软雅黑", 10),
            fg="#FF6F00"
        )
        self.hs_label.pack(side=tk.RIGHT)

        # ===== 题目区 =====
        q_frame = tk.LabelFrame(self.root, text="题目", font=("微软雅黑", 10))
        q_frame.pack(padx=20, pady=8, fill=tk.X)

        self.question_label = tk.Label(
            q_frame, text="点击“开始训练”按钮开始！",
            font=("Consolas", 24, "bold"), fg="#1565C0"
        )
        self.question_label.pack(pady=15)

        answer_frame = tk.Frame(q_frame)
        answer_frame.pack(pady=8)

        tk.Label(answer_frame, text="你的答案：", font=("微软雅黑", 11)).pack(side=tk.LEFT)

        self.answer_entry = tk.Entry(answer_frame, width=12, font=("Consolas", 16))
        self.answer_entry.pack(side=tk.LEFT, padx=5)
        self.answer_entry.bind("<Return>", lambda e: self.check_answer())
        self.answer_entry.config(state="disabled")

        tk.Button(
            answer_frame, text="提交", bg="#4CAF50", fg="white",
            font=("微软雅黑", 10, "bold"),
            command=self.check_answer
        ).pack(side=tk.LEFT, padx=8)

        # ===== 反馈区 =====
        self.feedback_label = tk.Label(self.root, text="", font=("微软雅黑", 12))
        self.feedback_label.pack(pady=3)

        # ===== 统计区 =====
        stat_frame = tk.LabelFrame(self.root, text="统计", font=("微软雅黑", 10))
        stat_frame.pack(padx=20, pady=5, fill=tk.X)

        self.stat_label = tk.Label(
            stat_frame,
            text="正确：0  错误：0  正确率：--%  用时：--",
            font=("Consolas", 10)
        )
        self.stat_label.pack(anchor="w", padx=10, pady=5)

        # ===== 设置区 =====
        setting_frame = tk.Frame(self.root)
        setting_frame.pack(pady=5)

        tk.Label(setting_frame, text="运算类型：", font=("微软雅黑", 9)).pack(side=tk.LEFT)

        self.mode = tk.StringVar(value="混合")
        for text in ["加法", "减法", "乘法", "除法", "混合"]:
            tk.Radiobutton(
                setting_frame, text=text, variable=self.mode,
                value=text, font=("微软雅黑", 9)
            ).pack(side=tk.LEFT, padx=5)

        tk.Label(setting_frame, text="    难度：", font=("微软雅黑", 9)).pack(side=tk.LEFT)

        self.diff_var = tk.StringVar(value="100")
        for text, val in [("简单(10)", "10"), ("中等(100)", "100"), ("困难(1000)", "1000")]:
            tk.Radiobutton(
                setting_frame, text=text, variable=self.diff_var,
                value=val, font=("微软雅黑", 9)
            ).pack(side=tk.LEFT, padx=3)

        # ===== 按钮区 =====
        btn_frame = tk.Frame(self.root)
        btn_frame.pack(pady=10)

        self.start_btn = tk.Button(
            btn_frame, text="▶ 开始训练",
            width=14, height=2,
            bg="#4CAF50", fg="white",
            font=("微软雅黑", 11, "bold"),
            command=self.start_quiz
        )
        self.start_btn.pack(side=tk.LEFT, padx=8)

        tk.Button(
            btn_frame, text="重置记录",
            width=12, height=2,
            bg="#FF9800", fg="white",
            font=("微软雅黑", 10),
            command=self.reset_score
        ).pack(side=tk.LEFT, padx=8)

        tk.Button(
            btn_frame, text="退出",
            width=10, height=2,
            bg="#f44336", fg="white",
            font=("微软雅黑", 10),
            command=self.root.quit
        ).pack(side=tk.LEFT, padx=8)

    # ========== 出题逻辑 ==========
    def generate_question(self):
        rng = int(self.diff_var.get())
        mode = self.mode.get()

        if mode == "混合":
            mode = random.choice(["加法", "减法", "乘法", "除法"])

        if mode == "加法":
            a = random.randint(1, rng)
            b = random.randint(1, rng)
            self.current_answer = a + b
            self.question_label.config(text=str(a) + " + " + str(b) + " = ?")

        elif mode == "减法":
            a = random.randint(1, rng)
            b = random.randint(1, a)
            self.current_answer = a - b
            self.question_label.config(text=str(a) + " − " + str(b) + " = ?")

        elif mode == "乘法":
            a = random.randint(1, min(12, rng))
            b = random.randint(1, min(12, rng))
            self.current_answer = a * b
            self.question_label.config(text=str(a) + " × " + str(b) + " = ?")

        elif mode == "除法":
            b = random.randint(1, min(12, rng))
            self.current_answer = random.randint(1, min(12, rng))
            a = self.current_answer * b
            self.question_label.config(text=str(a) + " ÷ " + str(b) + " = ?")

        self.answer_entry.delete(0, tk.END)
        self.feedback_label.config(text="")
        self.answer_entry.focus()

    def check_answer(self):
        if not self.running:
            return
        try:
            user_ans = int(self.answer_entry.get().strip())
        except ValueError:
            self.feedback_label.config(text="⚠️ 请输入数字！", fg="#FF9800")
            return

        self.total += 1
        if user_ans == self.current_answer:
            self.score += 1
            self.feedback_label.config(text="✅ 正确！", fg="#4CAF50")
        else:
            self.feedback_label.config(
                text="❌ 错误！正确答案是：" + str(self.current_answer),
                fg="#E53935"
            )

        self.update_stat()
        self.root.after(600, self.generate_question)

    def update_stat(self):
        rate = (self.score / self.total * 100) if self.total else 0
        elapsed = int(time.time() - self.start_time) if hasattr(self, 'start_time') else 0
        self.stat_label.config(
            text="正确：" + str(self.score) +
            "  错误：" + str(self.total - self.score) +
            "  正确率：" + str(round(rate, 1)) + "%" +
            "  用时：" + str(elapsed) + "秒"
        )

    # ========== 计时器 ==========
    def start_quiz(self):
        self.score = 0
        self.total = 0
        self.running = True
        self.start_time = time.time()

        self.start_btn.config(state="disabled")
        self.answer_entry.config(state="normal")
        self.answer_entry.delete(0, tk.END)
        self.feedback_label.config(text="")
        self.update_stat()

        self.time_limit = 60
        self.remaining = self.time_limit

        self.update_timer()
        self.generate_question()

        threading.Thread(target=self.run_timer, daemon=True).start()

    def run_timer(self):
        while self.running and self.remaining > 0:
            time.sleep(1)
            self.remaining -= 1
            self.root.after(0, self.update_timer)
        if self.running:
            self.root.after(0, self.time_up)

    def update_timer(self):
        self.timer_label.config(
            text="⏱️ " + str(self.remaining) + " / " + str(self.time_limit) + " 秒"
        )
        if self.remaining <= 10:
            self.timer_label.config(fg="#E53935")
        else:
            self.timer_label.config(fg="#2E7D32")

    def time_up(self):
        self.running = False
        self.start_btn.config(state="normal")
        self.answer_entry.config(state="disabled")

        rate = (self.score / self.total * 100) if self.total else 0

        is_new_record = False
        if self.score > self.high_score:
            self.high_score = self.score
            self.save_high_score()
            is_new_record = True
            self.hs_label.config(text="最高分：" + str(self.high_score))

        result = (
            "⏰ 时间到！\n\n"
            "总题数：" + str(self.total) + "\n"
            "正确：" + str(self.score) + "\n"
            "正确率：" + str(round(rate, 1)) + "%\n"
            "平均每题：" + str(round(60 / max(self.total, 1), 1)) + " 秒"
        )
        if is_new_record:
            result += "\n\n🎉 新纪录！"

        self.question_label.config(text="⏰ 时间到！")
        messagebox.showinfo("训练结束", result)

    def reset_score(self):
        if messagebox.askyesno("确认", "重置最高分记录？"):
            self.high_score = 0
            self.save_high_score()
            self.hs_label.config(text="最高分：0")
            self.stat_label.config(text="正确：0  错误：0  正确率：--%  用时：--")
            self.feedback_label.config(text="")
            self.question_label.config(text="点击“开始训练”按钮开始！")
            self.timer_label.config(text="⏱️ 准备就绪", fg="#E53935")


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