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

# 打字题库（可自行添加中文/英文）
text_lib = [
    "人生如逆旅，我亦是行人。用心做好当下每一件小事。",
    "Practice your typing every day, speed and accuracy will improve gradually.",
    "书山有路勤为径，学海无涯苦作舟。坚持练习才能不断进步。",
    "Where there is a will, there is a way. Never stop your practice.",
    "一寸光阴一寸金，寸金难买寸光阴，珍惜时间认真练习打字。"
]

class TypingTest:
    def __init__(self, root):
        self.win = root
        self.win.title("打字练习软件｜字数+正确率统计")
        self.win.geometry("750x520")

        # 全局变量
        self.start_time = None
        self.is_running = False
        self.target_str = ""  # 目标范文

        # 标题
        tk.Label(self.win, text="打字练习", font=("微软雅黑", 20, "bold")).pack(pady=10)

        # 范文区域
        tk.Label(self.win, text="【对照范文】", font=("微软雅黑", 12)).pack()
        self.show_text = tk.Text(self.win, height=5, width=90, font=("Consolas",12))
        self.show_text.pack(padx=10)

        # 输入区域【先创建控件，再调用加载文本】
        tk.Label(self.win, text="【在此输入内容】", font=("微软雅黑",12)).pack(pady=5)
        self.input_text = tk.Text(self.win, height=7, width=90, font=("Consolas",12))
        self.input_text.pack(padx=10)
        # 首次按键启动计时
        self.input_text.bind("<Key>", self.start_timer)

        # 数据统计面板
        frame_data = tk.Frame(self.win)
        frame_data.pack(pady=12)

        tk.Label(frame_data, text="用时:", font=("微软雅黑",11)).grid(row=0,column=0,padx=6)
        self.lab_time = tk.Label(frame_data, text="0.0s", width=7, bg="#eeeeee")
        self.lab_time.grid(row=0,column=1,padx=6)

        tk.Label(frame_data, text="总输入字数:", font=("微软雅黑",11)).grid(row=0,column=2,padx=6)
        self.lab_total = tk.Label(frame_data, text="0", width=7, bg="#eeeeee")
        self.lab_total.grid(row=0,column=3,padx=6)

        tk.Label(frame_data, text="正确字数:", font=("微软雅黑",11)).grid(row=0,column=4,padx=6)
        self.lab_right = tk.Label(frame_data, text="0", width=7, bg="#eeeeee")
        self.lab_right.grid(row=0,column=5,padx=6)

        tk.Label(frame_data, text="正确率:", font=("微软雅黑",11)).grid(row=0,column=6,padx=6)
        self.lab_rate = tk.Label(frame_data, text="0%", width=7, bg="#eeeeee")
        self.lab_rate.grid(row=0,column=7,padx=6)

        # 按钮区
        frame_btn = tk.Frame(self.win)
        frame_btn.pack()
        ttk.Button(frame_btn, text="更换新文章", command=self.load_new_text).grid(row=0,column=0,padx=10)
        ttk.Button(frame_btn, text="清空输入", command=self.clear_all).grid(row=0,column=1,padx=10)
        ttk.Button(frame_btn, text="计算成绩", command=self.count_result).grid(row=0,column=2,padx=10)

        # 所有控件创建完成后再加载文本
        self.load_new_text()
        # 定时器循环刷新时间
        self.update_time()

    # 随机加载新范文
    def load_new_text(self):
        self.target_str = random.choice(text_lib)
        self.show_text.config(state=tk.NORMAL)
        self.show_text.delete(1.0, tk.END)
        self.show_text.insert(tk.END, self.target_str)
        self.show_text.config(state=tk.DISABLED)
        self.clear_all()

    # 清空输入框+重置数据
    def clear_all(self):
        self.input_text.delete(1.0, tk.END)
        self.start_time = None
        self.is_running = False
        self.lab_time.config(text="0.0s")
        self.lab_total.config(text="0")
        self.lab_right.config(text="0")
        self.lab_rate.config(text="0%")

    # 第一次按下键盘启动计时
    def start_timer(self, event):
        if not self.is_running:
            self.start_time = time.time()
            self.is_running = True

    # 实时刷新用时
    def update_time(self):
        if self.is_running and self.start_time:
            use = round(time.time() - self.start_time,1)
            self.lab_time.config(text=f"{use}s")
        self.win.after(100, self.update_time)

    # 统计：总输入字符、正确字符、正确率
    def count_result(self):
        user = self.input_text.get(1.0, tk.END).strip("\n")
        target = self.target_str

        total_input = len(user)
        right = 0
        min_len = min(len(user), len(target))
        # 逐字符比对正误
        for u_char,t_char in zip(user[:min_len], target[:min_len]):
            if u_char == t_char:
                right += 1
        # 计算正确率
        if len(target) == 0:
            rate = 0.0
        else:
            rate = round((right / len(target)) * 100, 2)

        # 更新界面数据
        self.lab_total.config(text=str(total_input))
        self.lab_right.config(text=str(right))
        self.lab_rate.config(text=f"{rate}%")

        # 弹窗成绩单
        msg = f"范文总字符：{len(target)}\n你输入总字数：{total_input}\n正确字数：{right}\n正确率：{rate}%"
        messagebox.showinfo("打字成绩", msg)

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