import tkinter as tk
import random
import time
import math

# ========================
# 全局配置
# ========================
WIDTH, HEIGHT = 800, 600

# ========================
# 主题
# ========================
THEMES = {
    "🌸 樱花粉": {"bg": "#FFF0F5", "fg": "#C2185B", "panel": "#FCE4EC", "btn": "#F48FB1", "accent": "#E91E63"},
    "💙 天空蓝": {"bg": "#E3F2FD", "fg": "#0D47A1", "panel": "#90CAF9", "btn": "#42A5F5", "accent": "#1E88E5"},
    "💚 抹茶绿": {"bg": "#E8F5E9", "fg": "#1B5E20", "panel": "#A5D6A7", "btn": "#66BB6A", "accent": "#388E3C"},
    "🧡 蜜桔橙": {"bg": "#FFF3E0", "fg": "#E65100", "panel": "#FFCC80", "btn": "#FF9800", "accent": "#F57C00"},
    "💜 梦幻紫": {"bg": "#F3E5F5", "fg": "#4A148C", "panel": "#CE93D8", "btn": "#AB47BC", "accent": "#7B1FA2"},
    "🌈 糖果色": {"bg": "#FFF9C4", "fg": "#F57F17", "panel": "#FFF176", "btn": "#FFD54F", "accent": "#FF8F00"},
}
cur_theme = "🌸 樱花粉"

# ========================
# 练习模式数据
# ========================
modes = {
    "add":      {"name": "加法练习", "op": "+", "emoji": "➕", "gen": lambda: (random.randint(1, 99), random.randint(1, 99))},
    "sub":      {"name": "减法练习", "op": "-", "emoji": "➖", "gen": lambda: (random.randint(10, 99), random.randint(1, 10))},
    "mul":      {"name": "乘法练习", "op": "×", "emoji": "✖️", "gen": lambda: (random.randint(2, 12), random.randint(2, 12))},
    "div":      {"name": "除法练习", "op": "÷", "emoji": "➗", "gen": lambda: (random.randint(2, 12), random.randint(2, 12))},
    "mix":      {"name": "混合四则", "op": "?", "emoji": "🎲", "gen": None},
    "table":    {"name": "乘法表",   "op": "×", "emoji": "📊", "gen": None},
}

# ========================
# 状态
# ========================
cur_mode = "add"
score = 0
total = 0
streak = 0
best_streak = 0
start_time = 0
elapsed = 0
answer_correct = True
feedback_timer = 0
mul_table_num = 2  # 乘法表当前数字

a, b, op = 0, 0, "+"
correct_answer = 0

# ========================
# UI 引用
# ========================
root = None
canvas = None
entry_answer = None
lbl_score = None
lbl_streak = None
lbl_time = None
lbl_question = None
lbl_feedback = None
lbl_stats = None
mode_btns = {}
theme_btns = []
all_widgets = []

# ========================
# 数学题生成
# ========================
def generate_question():
    """生成题目"""
    global a, b, op, correct_answer

    if cur_mode == "mix":
        ops = ["+", "-", "×", "÷"]
        op = random.choice(ops)
        if op == "+":
            a, b = random.randint(1, 50), random.randint(1, 50)
            correct_answer = a + b
        elif op == "-":
            a, b = random.randint(10, 99), random.randint(1, a)
            correct_answer = a - b
        elif op == "×":
            a, b = random.randint(2, 12), random.randint(2, 12)
            correct_answer = a * b
        else:
            b = random.randint(2, 12)
            ans = random.randint(2, 12)
            a = b * ans
            correct_answer = ans
    elif cur_mode == "table":
        a = mul_table_num
        b = random.randint(1, 12)
        op = "×"
        correct_answer = a * b
    else:
        gen = modes[cur_mode]["gen"]
        a, b = gen()
        op = modes[cur_mode]["op"]
        if op == "+":
            correct_answer = a + b
        elif op == "-":
            correct_answer = a - b
        elif op == "×":
            correct_answer = a * b
        elif op == "÷":
            ans = b
            b = random.randint(2, 12)
            a = b * ans
            correct_answer = ans

    draw_question()

def check_answer():
    """检查答案"""
    global score, total, streak, best_streak, answer_correct, feedback_timer

    user_input = entry_answer.get().strip()
    if not user_input:
        return

    try:
        user_ans = int(user_input)
    except:
        show_feedback("❌ 请输入数字！", "#F44336")
        return

    total += 1
    if user_ans == correct_answer:
        score += 1
        streak += 1
        best_streak = max(best_streak, streak)
        answer_correct = True
        show_feedback("✅ 正确！", "#4CAF50")
        # 特效
        particles.append({"x": WIDTH//2, "y": HEIGHT//2 - 50, "life": 20, "type": "correct"})
    else:
        streak = 0
        answer_correct = False
        show_feedback(f"❌ 错了！答案是 {correct_answer}", "#F44336")
        particles.append({"x": WIDTH//2, "y": HEIGHT//2 - 50, "life": 20, "type": "wrong"})

    entry_answer.delete(0, "end")
    update_stats()
    generate_question()

def show_feedback(text, color):
    """显示反馈"""
    global feedback_timer
    lbl_feedback.config(text=text, fg=color)
    feedback_timer = 60

# ========================
# 乘法表
# ========================
def draw_multiplication_table():
    """绘制完整乘法表"""
    canvas.delete("all")
    t = THEMES[cur_theme]

    # 标题
    canvas.create_text(WIDTH//2, 30, text=f"📊 {mul_table_num} 的乘法表",
                       font=("Comic Sans MS", 18, "bold"), fill=t["fg"])

    # 表格
    start_y = 70
    row_h = 32
    for i in range(1, 13):
        y = start_y + (i-1) * row_h
        ans = mul_table_num * i

        # 行背景
        bg = t["panel"] if i % 2 == 1 else t["bg"]
        canvas.create_rectangle(150, y - 12, WIDTH - 150, y + 18, fill=bg, outline="")

        # 公式
        text = f"{mul_table_num} × {i} = {ans}"
        canvas.create_text(WIDTH//2, y + 3, text=text,
                           font=("Comic Sans MS", 14, "bold"), fill=t["fg"])

        # 高亮当前
        if i == b:
            canvas.create_rectangle(200, y - 14, WIDTH - 200, y + 20,
                                    outline=t["accent"], width=2)

    # 底部提示
    canvas.create_text(WIDTH//2, HEIGHT - 40,
                       text="💡 上方是完整乘法表，右侧可切换数字 | 做题模式请选其他模式",
                       font=("Comic Sans MS", 10), fill=t["accent"])

def set_table_num(n):
    """设置乘法表数字"""
    global mul_table_num
    mul_table_num = n
    if cur_mode == "table":
        draw_multiplication_table()
        generate_question()

# ========================
# 绘制题目
# ========================
def draw_question():
    """在画布上绘制大号题目"""
    if cur_mode == "table":
        draw_multiplication_table()
        return

    canvas.delete("all")
    t = THEMES[cur_theme]

    # 背景装饰
    for i in range(5):
        y = 20 + i * 30
        canvas.create_oval(random.randint(10, 60), y, random.randint(20, 70), y+8,
                           fill=t["panel"], outline="")

    # 模式标题
    m = modes[cur_mode]
    canvas.create_text(WIDTH//2, 25, text=f"{m['emoji']} {m['name']}",
                       font=("Comic Sans MS", 14, "bold"), fill=t["accent"])

    # 大号题目
    q_text = f"{a}  {op}  {b}  =  ?"
    canvas.create_text(WIDTH//2, HEIGHT//2 - 30, text=q_text,
                       font=("Comic Sans MS", 36, "bold"), fill=t["fg"])

    # 输入框提示
    canvas.create_text(WIDTH//2, HEIGHT//2 + 30, text="👇 在下方输入框填写答案后回车",
                       font=("Comic Sans MS", 11), fill=t["accent"])

    # 进度提示
    canvas.create_text(WIDTH//2, HEIGHT - 50,
                       text=f"第 {total+1} 题 | 当前连对: {streak}",
                       font=("Comic Sans MS", 11), fill=t["fg"])

# ========================
# 粒子特效
# ========================
particles = []

def draw_particles():
    """绘制粒子"""
    for p in particles[:]:
        p["life"] -= 1
        alpha = p["life"] / 20
        if p["type"] == "correct":
            colors = ["#4CAF50", "#8BC34A", "#CDDC39", "#FFEB3B"]
            c = colors[20 - p["life"]]
            size = 3 + int(alpha * 5)
            for angle in range(0, 360, 45):
                rad = math.radians(angle)
                px = p["x"] + int(30 * alpha * math.cos(rad))
                py = p["y"] + int(30 * alpha * math.sin(rad))
                canvas.create_oval(px-size, py-size, px+size, py+size, fill=c, outline="")
        else:
            colors = ["#F44336", "#FF5722", "#FF9800"]
            c = colors[20 - p["life"] % 3]
            size = 2 + int(alpha * 4)
            for angle in range(0, 360, 60):
                rad = math.radians(angle)
                px = p["x"] + int(20 * alpha * math.cos(rad))
                py = p["y"] + int(20 * alpha * math.sin(rad))
                canvas.create_oval(px-size, py-size, px+size, py+size, fill=c, outline="")
        if p["life"] <= 0:
            particles.remove(p)

# ========================
# 统计
# ========================
def update_stats():
    """更新统计"""
    lbl_score.config(text=f"⭐ 得分: {score}/{total}")
    lbl_streak.config(text=f"🔥 连对: {streak} (最高:{best_streak})")
    accuracy = (score / total * 100) if total > 0 else 0
    elapsed_s = int(time.time() - start_time)
    m, s = elapsed_s // 60, elapsed_s % 60
    lbl_time.config(text=f"⏱ {m:02d}:{s:02d}")
    lbl_stats.config(text=f"📊 正确率: {accuracy:.0f}%")

def reset_stats():
    """重置统计"""
    global score, total, streak, best_streak, start_time
    score = 0
    total = 0
    streak = 0
    best_streak = 0
    start_time = time.time()
    update_stats()
    generate_question()

# ========================
# 模式切换
# ========================
def set_mode(mode):
    """切换模式"""
    global cur_mode
    cur_mode = mode
    for name, btn in mode_btns.items():
        if name == mode:
            btn.config(relief="sunken", bd=3)
        else:
            btn.config(relief="raised", bd=1)
    reset_stats()

# ========================
# 换肤
# ========================
def apply_theme(name):
    """换肤"""
    global cur_theme
    cur_theme = name
    t = THEMES[name]

    root.config(bg=t["bg"])
    for w in all_widgets:
        try:
            w.config(bg=t["bg"], fg=t["fg"])
        except:
            pass

    for btn in theme_btns:
        btn.config(bg=t["btn"], fg="white")

    for name, btn in mode_btns.items():
        btn.config(bg=t["panel"])

    # 重绘
    draw_question()

# ========================
# 键盘
# ========================
def on_key(e):
    if e.keysym == "Return" or e.keysym == "Enter":
        check_answer()
    elif e.keysym == "Escape":
        entry_answer.delete(0, "end")
    elif e.keysym == "r" or e.keysym == "R":
        reset_stats()

# ========================
# 主循环
# ========================
def game_loop():
    """主循环"""
    global feedback_timer

    draw_particles()
    feedback_timer -= 1
    if feedback_timer <= 0:
        lbl_feedback.config(text="")

    # 计时
    if start_time > 0:
        elapsed_s = int(time.time() - start_time)
        m, s = elapsed_s // 60, elapsed_s % 60
        lbl_time.config(text=f"⏱ {m:02d}:{s:02d}")

    root.after(50, game_loop)

# ========================
# 构建界面
# ========================
def build_ui():
    """构建界面"""
    global root, canvas, entry_answer, lbl_score, lbl_streak
    global lbl_time, lbl_question, lbl_feedback, lbl_stats
    global mode_btns, theme_btns, all_widgets

    root = tk.Tk()
    root.title("🧮 计算小能手 · 数学题练习器")
    root.geometry(f"{WIDTH}x{HEIGHT}")
    root.resizable(False, False)

    # ====== 顶部状态栏 ======
    top = tk.Frame(root, height=36)
    top.pack(fill="x", side="top")

    lbl_score = tk.Label(top, text="⭐ 得分: 0/0", font=("Comic Sans MS", 12, "bold"))
    lbl_score.pack(side="left", padx=10)

    lbl_streak = tk.Label(top, text="🔥 连对: 0 (最高:0)", font=("Comic Sans MS", 11))
    lbl_streak.pack(side="left", padx=10)

    lbl_time = tk.Label(top, text="⏱ 00:00", font=("Comic Sans MS", 11))
    lbl_time.pack(side="left", padx=10)

    lbl_stats = tk.Label(top, text="📊 正确率: 0%", font=("Comic Sans MS", 11))
    lbl_stats.pack(side="left", padx=10)

    btn_reset = tk.Button(top, text="🔄 重置", font=("Comic Sans MS", 10, "bold"),
                           command=reset_stats)
    btn_reset.pack(side="right", padx=10)

    # ====== 主题栏 ======
    theme_bar = tk.Frame(root)
    theme_bar.pack(fill="x", pady=2)

    tk.Label(theme_bar, text="🎨 ", font=("Comic Sans MS", 9)).pack(side="left", padx=5)
    for name in THEMES:
        btn = tk.Button(theme_bar, text=name, font=("Comic Sans MS", 8, "bold"),
                         relief="raised", bd=1, padx=4,
                         command=lambda n=name: apply_theme(n))
        btn.pack(side="left", padx=2)
        theme_btns.append(btn)

    # ====== 模式栏 ======
    mode_bar = tk.Frame(root)
    mode_bar.pack(fill="x", pady=3)

    tk.Label(mode_bar, text="📝 模式：", font=("Comic Sans MS", 10, "bold")).pack(side="left", padx=5)

    for key, m in modes.items():
        btn = tk.Button(mode_bar, text=f"{m['emoji']} {m['name']}",
                         font=("Comic Sans MS", 9, "bold"),
                         relief="raised", bd=1, padx=6,
                         command=lambda k=key: set_mode(k))
        btn.pack(side="left", padx=3)
        mode_btns[key] = btn

    # 乘法表数字选择
    tk.Label(mode_bar, text="  乘法表数字：", font=("Comic Sans MS", 9)).pack(side="left", padx=(15, 3))
    for n in range(2, 10):
        btn = tk.Button(mode_bar, text=str(n), width=2,
                         font=("Comic Sans MS", 9, "bold"),
                         command=lambda x=n: set_table_num(x))
        btn.pack(side="left", padx=1)

    # ====== 画布（题目区域）======
    canvas_frame = tk.Frame(root)
    canvas_frame.pack(fill="both", expand=True, padx=5, pady=5)

    canvas = tk.Canvas(canvas_frame, width=WIDTH-20, height=300, highlightthickness=0)
    canvas.pack(fill="both", expand=True)

    # ====== 输入区 ======
    input_bar = tk.Frame(root)
    input_bar.pack(fill="x", pady=8)

    tk.Label(input_bar, text="✏️ 你的答案：", font=("Comic Sans MS", 13, "bold")).pack(side="left", padx=15)

    entry_answer = tk.Entry(input_bar, font=("Comic Sans MS", 16, "bold"),
                             width=10, justify="center", relief="solid", bd=2)
    entry_answer.pack(side="left", padx=5)
    entry_answer.focus_set()

    btn_submit = tk.Button(input_bar, text="✅ 提交 (Enter)",
                            font=("Comic Sans MS", 12, "bold"),
                            bg="#4CAF50", fg="white", padx=10,
                            command=check_answer)
    btn_submit.pack(side="left", padx=10)

    btn_next = tk.Button(input_bar, text="⏭️ 跳过",
                          font=("Comic Sans MS", 11),
                          bg="#FF9800", fg="white", padx=8,
                          command=lambda: [generate_question(), entry_answer.delete(0, "end")])
    btn_next.pack(side="left", padx=5)

    # ====== 反馈 + 底部 ======
    lbl_feedback = tk.Label(root, text="", font=("Comic Sans MS", 14, "bold"))
    lbl_feedback.pack(pady=2)

    bottom = tk.Frame(root)
    bottom.pack(fill="x", side="bottom", pady=3)

    tk.Label(bottom, text="💡 Enter提交 | Esc清空 | R重置 | 连对越多越厉害 🔥",
             font=("Comic Sans MS", 9)).pack(pady=2)

    # 收集
    all_widgets.extend([lbl_score, lbl_streak, lbl_time, lbl_stats, lbl_feedback,
                        top, theme_bar, mode_bar, input_bar, bottom, btn_reset])

    # 绑定
    root.bind("<Key>", on_key)

# ========================
# 启动
# ========================
def init():
    build_ui()
    apply_theme("🌸 樱花粉")
    set_mode("add")
    global start_time
    start_time = time.time()
    generate_question()
    game_loop()

if __name__ == "__main__":
    init()
    root.mainloop()
