"""
数学题练习器 —— 计算小能手
功能：四则运算练习 + 乘法表查看
"""

import tkinter as tk
from tkinter import ttk, messagebox
import random
import time


# ==================== 四则运算练习模块 ====================

class ArithmeticQuiz:
    """四则运算出题与判题"""

    OPERATORS = ['+', '-', '×', '÷']

    def __init__(self):
        self.reset()

    def reset(self):
        self.score = 0
        self.total = 0
        self.streak = 0       # 连续答对
        self.best_streak = 0
        self.current_answer = None
        self.current_question = ""

    def generate(self, difficulty='简单', op_set=None):
        """生成一道题，返回 (题目字符串, 正确答案)"""
        if op_set is None:
            op_set = self.OPERATORS

        op = random.choice(op_set)

        if difficulty == '简单':
            if op in ('+', '-'):
                a = random.randint(1, 20)
                b = random.randint(1, 20)
            elif op == '×':
                a = random.randint(1, 9)
                b = random.randint(1, 9)
            else:  # ÷
                b = random.randint(1, 9)
                ans = random.randint(1, 9)
                a = b * ans
        elif difficulty == '中等':
            if op in ('+', '-'):
                a = random.randint(10, 99)
                b = random.randint(10, 99)
            elif op == '×':
                a = random.randint(2, 25)
                b = random.randint(2, 25)
            else:
                b = random.randint(2, 12)
                ans = random.randint(2, 12)
                a = b * ans
        else:  # 困难
            if op in ('+', '-'):
                a = random.randint(50, 999)
                b = random.randint(50, 999)
            elif op == '×':
                a = random.randint(10, 99)
                b = random.randint(10, 99)
            else:
                b = random.randint(2, 25)
                ans = random.randint(2, 25)
                a = b * ans

        # 减法保证非负
        if op == '-' and a < b:
            a, b = b, a
        # 除法用预计算的 ans
        if op == '÷':
            question = f"{a} ÷ {b}"
            return question, ans

        question = f"{a} {op} {b}"
        if op == '+':
            ans = a + b
        elif op == '-':
            ans = a - b
        elif op == '×':
            ans = a * b
        else:
            ans = None  # 不会到这里

        return question, ans

    def check(self, question, user_input):
        try:
            user_ans = int(user_input)
        except ValueError:
            return False, "请输入有效数字"
        self.total += 1
        if user_ans == self.current_answer:
            self.score += 1
            self.streak += 1
            self.best_streak = max(self.best_streak, self.streak)
            return True, "✅ 回答正确！"
        else:
            self.streak = 0
            return False, f"❌ 答错了，正确答案是 {self.current_answer}"


# ==================== 主应用 ====================

class MathPracticeApp:
    def __init__(self, root):
        self.root = root
        self.root.title("🧮 计算小能手 —— 数学题练习器")
        self.root.geometry("720x560")
        self.root.minsize(680, 520)
        self.root.configure(bg="#F5F5F0")

        # 样式
        self.style = ttk.Style()
        try:
            self.style.theme_use('clam')
        except:
            pass
        self.style.configure('TNotebook.Tab', font=('Microsoft YaHei', 11, 'bold'))
        self.style.configure('Title.TLabel', font=('Microsoft YaHei', 18, 'bold'), background='#F5F5F0', foreground='#2C3E50')
        self.style.configure('Info.TLabel', font=('Microsoft YaHei', 11), background='#F5F5F0', foreground='#34495E')
        self.style.configure('Big.TLabel', font=('Microsoft YaHei', 28, 'bold'), background='#FFFFFF', foreground='#E74C3C')
        self.style.configure('Feedback.TLabel', font=('Microsoft YaHei', 12), background='#F5F5F0')
        self.style.configure('TButton', font=('Microsoft YaHei', 11))
        self.style.configure('Accent.TButton', font=('Microsoft YaHei', 12, 'bold'))

        self.quiz = ArithmeticQuiz()
        self.start_time = None
        self.timer_running = False

        self._build_ui()

    # ---------- UI 构建 ----------
    def _build_ui(self):
        # 顶部标题
        header = tk.Frame(self.root, bg="#2C3E50", height=56)
        header.pack(fill=tk.X)
        header.pack_propagate(False)
        tk.Label(header, text="🧮 计算小能手  ·  数学题练习器",
                 font=('Microsoft YaHei', 18, 'bold'), bg="#2C3E50", fg="#ECF0F1").pack(pady=12)

        # Notebook 选项卡
        self.notebook = ttk.Notebook(self.root)
        self.notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=(10, 5))

        # 选项卡1：四则运算
        self.tab_quiz = tk.Frame(self.notebook, bg="#F5F5F0")
        self.notebook.add(self.tab_quiz, text="  ✏️ 四则运算练习  ")
        self._build_quiz_tab()

        # 选项卡2：乘法表
        self.tab_table = tk.Frame(self.notebook, bg="#F5F5F0")
        self.notebook.add(self.tab_table, text="  📊 乘法口诀表  ")
        self._build_table_tab()

        # 底部状态栏
        self.status_var = tk.StringVar(value="欢迎使用！点击「开始练习」按钮开始答题吧~")
        status_bar = tk.Label(self.root, textvariable=self.status_var,
                              font=('Microsoft YaHei', 10), bg="#ECF0F1", fg="#7F8C8D",
                              anchor=tk.W, padx=12, pady=4)
        status_bar.pack(fill=tk.X, side=tk.BOTTOM)

    # ========== 选项卡1：四则运算 ==========
    def _build_quiz_tab(self):
        tab = self.tab_quiz

        # 控制区
        ctrl = tk.LabelFrame(tab, text="⚙️ 设置", font=('Microsoft YaHei', 11, 'bold'),
                             bg="#F5F5F0", fg="#2C3E50", padx=12, pady=8)
        ctrl.pack(fill=tk.X, padx=12, pady=8)

        # 难度
        tk.Label(ctrl, text="难度：", font=('Microsoft YaHei', 11), bg="#F5F5F0").grid(row=0, column=0, padx=(0, 6))
        self.diff_var = tk.StringVar(value="简单")
        diff_combo = ttk.Combobox(ctrl, textvariable=self.diff_var, state="readonly", width=8,
                                   values=["简单", "中等", "困难"])
        diff_combo.grid(row=0, column=1, padx=4)

        # 运算类型
        tk.Label(ctrl, text="运算：", font=('Microsoft YaHei', 11), bg="#F5F5F0").grid(row=0, column=2, padx=(16, 6))
        self.op_vars = {
            '+': tk.BooleanVar(value=True),
            '-': tk.BooleanVar(value=True),
            '×': tk.BooleanVar(value=True),
            '÷': tk.BooleanVar(value=True),
        }
        for i, (sym, var) in enumerate(self.op_vars.items()):
            cb = tk.Checkbutton(ctrl, text=sym, variable=var, font=('Microsoft YaHei', 12, 'bold'),
                                bg="#F5F5F0", selectcolor="#DFE6E9")
            cb.grid(row=0, column=3 + i, padx=4)

        # 开始按钮
        ttk.Button(ctrl, text="▶ 开始练习", command=self.start_quiz,
                   style='Accent.TButton').grid(row=0, column=7, padx=(20, 0))
        ttk.Button(ctrl, text="🔄 重置", command=self.reset_quiz).grid(row=0, column=8, padx=6)

        ctrl.columnconfigure(7, weight=1)

        # 答题区
        quiz_area = tk.LabelFrame(tab, text="✏️ 答题区", font=('Microsoft YaHei', 11, 'bold'),
                                   bg="#F5F5F0", fg="#2C3E50", padx=16, pady=16)
        quiz_area.pack(fill=tk.BOTH, expand=True, padx=12, pady=(0, 8))

        self.question_var = tk.StringVar(value="点击「开始练习」出题")
        tk.Label(quiz_area, textvariable=self.question_var,
                 font=('Microsoft YaHei', 36, 'bold'), bg="#FFFFFF", fg="#E74C3C",
                 width=16, height=2, relief=tk.RAISED, bd=2).pack(pady=14)

        input_row = tk.Frame(quiz_area, bg="#F5F5F0")
        input_row.pack(pady=6)
        tk.Label(input_row, text="你的答案：", font=('Microsoft YaHei', 13, 'bold'), bg="#F5F5F0").pack(side=tk.LEFT)
        self.answer_entry = ttk.Entry(input_row, font=('Microsoft YaHei', 16, 'bold'),
                                       width=12, justify=tk.CENTER)
        self.answer_entry.pack(side=tk.LEFT, padx=8)
        self.answer_entry.bind('<Return>', lambda e: self.submit_answer())
        self.answer_entry.config(state=tk.DISABLED)

        btn_row = tk.Frame(quiz_area, bg="#F5F5F0")
        btn_row.pack(pady=10)
        ttk.Button(btn_row, text="✅ 提交答案", command=self.submit_answer,
                   style='Accent.TButton').pack(side=tk.LEFT, padx=6)
        ttk.Button(btn_row, text="⏭ 跳过", command=self.next_question).pack(side=tk.LEFT, padx=6)

        self.feedback_var = tk.StringVar(value="")
        self.feedback_label = tk.Label(quiz_area, textvariable=self.feedback_var,
                                        font=('Microsoft YaHei', 13, 'bold'), bg="#F5F5F0", fg="#2C3E50")
        self.feedback_label.pack(pady=6)

        # 统计区
        stats = tk.LabelFrame(tab, text="📈 战绩统计", font=('Microsoft YaHei', 11, 'bold'),
                              bg="#F5F5F0", fg="#2C3E50", padx=12, pady=8)
        stats.pack(fill=tk.X, padx=12, pady=(0, 10))

        self.stat_score = tk.StringVar(value="得分：0 / 0")
        self.stat_acc = tk.StringVar(value="正确率：0%")
        self.stat_streak = tk.StringVar(value="连击：0  🔥最佳：0")
        self.stat_time = tk.StringVar(value="用时：00:00")

        tk.Label(stats, textvariable=self.stat_score, font=('Microsoft YaHei', 11, 'bold'),
                 bg="#F5F5F0", fg="#2980B9").grid(row=0, column=0, padx=18)
        tk.Label(stats, textvariable=self.stat_acc, font=('Microsoft YaHei', 11, 'bold'),
                 bg="#F5F5F0", fg="#27AE60").grid(row=0, column=1, padx=18)
        tk.Label(stats, textvariable=self.stat_streak, font=('Microsoft YaHei', 11, 'bold'),
                 bg="#F5F5F0", fg="#E67E22").grid(row=0, column=2, padx=18)
        tk.Label(stats, textvariable=self.stat_time, font=('Microsoft YaHei', 11, 'bold'),
                 bg="#F5F5F0", fg="#8E44AD").grid(row=0, column=3, padx=18)

    # ========== 选项卡2：乘法表 ==========
    def _build_table_tab(self):
        tab = self.tab_table

        # 控制区
        ctrl = tk.Frame(tab, bg="#F5F5F0")
        ctrl.pack(fill=tk.X, padx=12, pady=8)

        tk.Label(ctrl, text="范围：", font=('Microsoft YaHei', 11), bg="#F5F5F0").pack(side=tk.LEFT)
        self.table_max = tk.IntVar(value=9)
        for v in [9, 12, 15, 20]:
            tk.Radiobutton(ctrl, text=f"{v}×{v}", variable=self.table_max, value=v,
                           font=('Microsoft YaHei', 11, 'bold'), bg="#F5F5F0",
                           selectcolor="#DFE6E9", command=self.refresh_table).pack(side=tk.LEFT, padx=6)

        ttk.Button(ctrl, text="🔍 高亮某行", command=self.highlight_row).pack(side=tk.LEFT, padx=(20, 4))
        self.highlight_var = tk.StringVar(value="")
        ttk.Entry(ctrl, textvariable=self.highlight_var, width=6, justify=tk.CENTER,
                  font=('Microsoft YaHei', 11)).pack(side=tk.LEFT, padx=4)

        # 表格区（Canvas + Scrollbar）
        table_frame = tk.Frame(tab, bg="#F5F5F0")
        table_frame.pack(fill=tk.BOTH, expand=True, padx=12, pady=(0, 12))

        self.canvas = tk.Canvas(table_frame, bg="#FFFFFF", highlightthickness=1, highlightbackground="#BDC3C7")
        hbar = ttk.Scrollbar(table_frame, orient=tk.HORIZONTAL, command=self.canvas.xview)
        vbar = ttk.Scrollbar(table_frame, orient=tk.VERTICAL, command=self.canvas.yview)
        self.canvas.configure(xscrollcommand=hbar.set, yscrollcommand=vbar.set)

        hbar.pack(side=tk.BOTTOM, fill=tk.X)
        vbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        self.table_inner = tk.Frame(self.canvas, bg="#FFFFFF")
        self.canvas.create_window((0, 0), window=self.table_inner, anchor=tk.NW)

        self.refresh_table()

    # ---------- 四则运算逻辑 ----------
    def start_quiz(self):
        # 检查至少选了一个运算符
        selected = [s for s, v in self.op_vars.items() if v.get()]
        if not selected:
            messagebox.showwarning("提示", "请至少选择一种运算符号！")
            return

        self.quiz.reset()
        self.start_time = time.time()
        self.timer_running = True
        self.answer_entry.config(state=tk.NORMAL)
        self.answer_entry.focus_set()
        self._tick_timer()
        self.status_var.set("练习中… 加油！")
        self.next_question()

    def reset_quiz(self):
        self.quiz.reset()
        self.timer_running = False
        self.question_var.set("点击「开始练习」出题")
        self.feedback_var.set("")
        self.answer_entry.config(state=tk.DISABLED)
        self.answer_entry.delete(0, tk.END)
        self.start_time = None
        self._update_stats()
        self.stat_time.set("用时：00:00")
        self.status_var.set("已重置，随时可以开始新的练习~")

    def next_question(self, event=None):
        if not self.timer_running:
            return
        selected = [s for s, v in self.op_vars.items() if v.get()]
        q, ans = self.quiz.generate(difficulty=self.diff_var.get(), op_set=selected)
        self.quiz.current_question = q
        self.quiz.current_answer = ans
        self.question_var.set(f"{q} = ?")
        self.answer_entry.delete(0, tk.END)
        self.answer_entry.focus_set()
        self.feedback_var.set("")
        self._update_stats()

    def submit_answer(self):
        if not self.timer_running:
            return
        user_input = self.answer_entry.get().strip()
        if not user_input:
            self.feedback_var.set("⚠️ 请输入答案")
            self.feedback_label.config(fg="#E67E22")
            return
        ok, msg = self.quiz.check(self.quiz.current_question, user_input)
        self.feedback_var.set(msg)
        self.feedback_label.config(fg="#27AE60" if ok else "#E74C3C")
        self._update_stats()
        # 0.8 秒后自动出下一题
        self.root.after(900, self.next_question)

    def _update_stats(self):
        q = self.quiz
        self.stat_score.set(f"得分：{q.score} / {q.total}")
        acc = (q.score / q.total * 100) if q.total else 0
        self.stat_acc.set(f"正确率：{acc:.0f}%")
        self.stat_streak.set(f"连击：{q.streak}  🔥最佳：{q.best_streak}")

    def _tick_timer(self):
        if self.timer_running and self.start_time:
            elapsed = int(time.time() - self.start_time)
            m, s = divmod(elapsed, 60)
            self.stat_time.set(f"用时：{m:02d}:{s:02d}")
            self.root.after(1000, self._tick_timer)

    # ---------- 乘法表逻辑 ----------
    def refresh_table(self):
        # 清掉旧控件
        for w in self.table_inner.winfo_children():
            w.destroy()

        n = self.table_max.get()
        colors = ["#FDEBD0", "#D5F5E3", "#D6EAF8", "#F5B7B1", "#E8DAEF",
                  "#F9E79F", "#D1F2EB", "#FADBD8", "#D4EFDF", "#FCF3CF"]

        # 表头行
        tk.Label(self.table_inner, text="×", font=('Microsoft YaHei', 12, 'bold'),
                 bg="#2C3E50", fg="white", width=5, height=2, relief=tk.RIDGE).grid(row=0, column=0, sticky="nsew")
        for j in range(1, n + 1):
            tk.Label(self.table_inner, text=str(j), font=('Microsoft YaHei', 12, 'bold'),
                     bg="#2C3E50", fg="white", width=6, height=2, relief=tk.RIDGE).grid(row=0, column=j, sticky="nsew")

        # 数据行
        for i in range(1, n + 1):
            # 行头
            tk.Label(self.table_inner, text=str(i), font=('Microsoft YaHei', 12, 'bold'),
                     bg="#2C3E50", fg="white", width=5, height=2, relief=tk.RIDGE).grid(row=i, column=0, sticky="nsew")
            bg_base = colors[(i - 1) % len(colors)]
            for j in range(1, n + 1):
                val = i * j
                bg = bg_base if i <= j else "#F8F9FA"
                fg = "#C0392B" if i == j else "#2C3E50"
                font_style = ('Microsoft YaHei', 11, 'bold') if i == j else ('Microsoft YaHei', 11)
                cell = tk.Label(self.table_inner, text=str(val), font=font_style,
                                bg=bg, fg=fg, width=6, height=2, relief=tk.RIDGE)
                cell.grid(row=i, column=j, sticky="nsew")
                # 悬停提示
                cell.bind("<Enter>", lambda e, x=i, y=j: self.status_var.set(f"💡 {x} × {y} = {x*y}"))
                cell.bind("<Leave>", lambda e: self.status_var.set(""))

        self.table_inner.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox(tk.ALL))

    def highlight_row(self):
        try:
            row = int(self.highlight_var.get().strip())
        except ValueError:
            messagebox.showinfo("提示", "请输入要高亮的行号（数字）")
            return
        n = self.table_max.get()
        if not (1 <= row <= n):
            messagebox.showinfo("提示", f"行号范围 1 ~ {n}")
            return
        # 简单实现：弹窗显示该行内容
        line = "  ".join(f"{row}×{j}={row*j}" for j in range(1, n + 1))
        messagebox.showinfo(f"第 {row} 行乘法口诀", line)


# ==================== 启动 ====================

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