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

# 练习文本库
text_lib = [
    "The quick brown fox jumps over the lazy dog. Python is a simple and powerful programming language.",
    "Life is not about waiting for the storm to pass, but learning how to dance in the rain.",
    "面朝大海，春暖花开。从明天起，做一个幸福的人，喂马、劈柴，周游世界。",
    "读书使人充实，思考使人深邃，交谈使人清醒。坚持每日练习，方能不断精进自我。",
    "Software development requires patience, careful thinking and continuous accumulation of experience."
]

class TypingPracticeApp:
    def __init__(self, root):
        self.root = root
        self.root.title("打字练习工具")
        self.root.geometry("750x520")
        self.root.resizable(False, False)

        # 变量初始化
        self.start_time = None
        self.is_start = False
        self.target_text = ""
        self.input_content = ""
        self.correct_count = 0
        self.total_char = 0

        self.create_widgets()
        self.random_new_text()

    def create_widgets(self):
        # 标题
        title_label = tk.Label(self.root, text="Python 打字练习软件", font=("微软雅黑", 18, "bold"))
        title_label.pack(pady=10)

        # 数据展示区（速度、正确率、用时）
        frame_stat = tk.Frame(self.root)
        frame_stat.pack(fill="x", padx=20)

        self.label_speed = tk.Label(frame_stat, text="打字速度：0 WPM", font=("微软雅黑", 11))
        self.label_speed.pack(side="left", padx=15)
        self.label_accuracy = tk.Label(frame_stat, text="正确率：0%", font=("微软雅黑", 11))
        self.label_accuracy.pack(side="left", padx=15)
        self.label_time = tk.Label(frame_stat, text="用时：0 s", font=("微软雅黑", 11))
        self.label_time.pack(side="left", padx=15)

        # 目标文本显示框（只读）
        tk.Label(self.root, text="【对照文本】", font=("微软雅黑", 12)).pack(anchor="w", padx=20, pady=(10, 2))
        self.text_target = tk.Text(self.root, height=6, width=85, font=("微软雅黑", 12), bg="#f0f0f0")
        self.text_target.pack(padx=20)
        self.text_target.config(state="disabled")

        # 输入区域
        tk.Label(self.root, text="【在此输入】", font=("微软雅黑", 12)).pack(anchor="w", padx=20, pady=(10, 2))
        self.text_input = tk.Text(self.root, height=6, width=85, font=("微软雅黑", 12))
        self.text_input.pack(padx=20)
        self.text_input.bind("<KeyRelease>", self.check_input)

        # 按钮区域
        frame_btn = tk.Frame(self.root)
        frame_btn.pack(pady=15)
        btn_new = ttk.Button(frame_btn, text="更换文本", command=self.random_new_text)
        btn_new.grid(row=0, column=0, padx=8)
        btn_reset = ttk.Button(frame_btn, text="重置练习", command=self.reset_all)
        btn_reset.grid(row=0, column=1, padx=8)
        btn_finish = ttk.Button(frame_btn, text="结束统计", command=self.finish_practice)
        btn_finish.grid(row=0, column=2, padx=8)

    def random_new_text(self):
        """随机加载一段练习文字"""
        self.reset_all()
        self.target_text = random.choice(text_lib)
        self.text_target.config(state="normal")
        self.text_target.delete(1.0, tk.END)
        self.text_target.insert(tk.END, self.target_text)
        self.text_target.config(state="disabled")

    def reset_all(self):
        """重置所有数据和输入框"""
        self.start_time = None
        self.is_start = False
        self.input_content = ""
        self.correct_count = 0
        self.total_char = 0
        self.text_input.delete(1.0, tk.END)
        self.label_speed.config(text="打字速度：0 WPM")
        self.label_accuracy.config(text="正确率：0%")
        self.label_time.config(text="用时：0 s")

    def check_input(self, event):
        """实时校验输入字符，标记对错，计时启动"""
        if not self.is_start:
            self.start_time = time.time()
            self.is_start = True

        self.input_content = self.text_input.get(1.0, tk.END).strip("\n")
        self.total_char = len(self.input_content)
        self.correct_count = 0

        # 计算正确字符数量
        min_len = min(len(self.input_content), len(self.target_text))
        for i in range(min_len):
            if self.input_content[i] == self.target_text[i]:
                self.correct_count += 1

        # 计算用时、速度、正确率
        use_time = round(time.time() - self.start_time, 1)
        if use_time > 0:
            # WPM：每分钟单词数（英文按5字符一个单词，中文单字计算）
            wpm = round((self.total_char / 5) / (use_time / 60), 1)
        else:
            wpm = 0

        if self.total_char > 0:
            accuracy = round((self.correct_count / self.total_char) * 100, 1)
        else:
            accuracy = 0

        # 更新界面数据
        self.label_speed.config(text=f"打字速度：{wpm} WPM")
        self.label_accuracy.config(text=f"正确率：{accuracy}%")
        self.label_time.config(text=f"用时：{use_time} s")

    def finish_practice(self):
        """结束练习弹窗展示最终成绩"""
        if not self.is_start or self.total_char == 0:
            messagebox.showinfo("提示", "请先输入内容再结束练习！")
            return
        use_time = round(time.time() - self.start_time, 1)
        wpm = round((self.total_char / 5) / (use_time / 60), 1) if use_time else 0
        accuracy = round((self.correct_count / self.total_char) * 100, 1)
        msg = f"=====本次练习报告=====\n总输入字符：{self.total_char}\n正确字符：{self.correct_count}\n正确率：{accuracy}%\n打字速度：{wpm} WPM\n耗时：{use_time} 秒"
        messagebox.showinfo("练习完成", msg)

if __name__ == "__main__":
    main_root = tk.Tk()
    app = TypingPracticeApp(main_root)
    main_root.mainloop()