import tkinter as tk
from tkinter import ttk, messagebox
import time


class App41:
    """タイピング速度テスト"""

    TEXTS = [
        "Python is a versatile programming language that is easy to learn.",
        "The quick brown fox jumps over the lazy dog.",
        "Programming is the art of telling another human what one wants the computer to do.",
        "In Python, indentation is used to define code blocks.",
        "Functions allow you to organize code into reusable pieces.",
    ]

    def __init__(self, root):
        self.root = root
        self.root.title("タイピング速度テスト")
        self.root.geometry("560x440")
        self.root.minsize(560, 440)
        self.root.configure(bg="#f8f9fc")
        self.start_time = None
        self.current_text = ""
        self._build_ui()
        self.new_test()

    def _build_ui(self):
        title_frame = tk.Frame(self.root, bg="#3776ab", pady=12)
        title_frame.pack(fill=tk.X)
        tk.Label(title_frame, text="タイピング速度テスト",
                 font=("Noto Sans JP", 16, "bold"),
                 bg="#3776ab", fg="white").pack()

        main_frame = tk.Frame(self.root, bg="#f8f9fc", padx=20, pady=14)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # お題テキスト
        text_frame = ttk.LabelFrame(main_frame, text="入力するテキスト", padding=10)
        text_frame.pack(fill=tk.X, pady=(0, 10))
        self.target_label = tk.Label(text_frame, text="", bg=self.root.cget("bg"),
                                     font=("Courier New", 12), wraplength=500,
                                     justify="left", anchor="w")
        self.target_label.pack(fill=tk.X)

        # 入力エリア
        input_frame = ttk.LabelFrame(main_frame, text="ここに入力してください", padding=10)
        input_frame.pack(fill=tk.X, pady=(0, 10))
        self.input_text = tk.Text(input_frame, font=("Courier New", 12), height=3,
                                  bg="white", fg="#333", wrap=tk.WORD,
                                  insertbackground="#3776ab")
        self.input_text.pack(fill=tk.X)
        self.input_text.bind("<KeyRelease>", self.on_type)

        # 統計
        stats_frame = tk.Frame(main_frame, bg="#f8f9fc")
        stats_frame.pack(fill=tk.X, pady=(0, 8))

        self.stat_labels = {}
        for col, (label, key) in enumerate([
            ("WPM", "wpm"), ("正確率", "accuracy"), ("経過時間", "elapsed"), ("進捗", "progress")
        ]):
            box = tk.Frame(stats_frame, bg="white", relief=tk.SOLID, bd=1, padx=12, pady=8)
            box.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=4)
            tk.Label(box, text=label, bg="white", fg="#888",
                     font=("Noto Sans JP", 9)).pack()
            lbl = tk.Label(box, text="--", bg="white", fg="#3776ab",
                           font=("Noto Sans JP", 16, "bold"))
            lbl.pack()
            self.stat_labels[key] = lbl

        # ボタン
        btn_frame = tk.Frame(main_frame, bg="#f8f9fc")
        btn_frame.pack()
        ttk.Button(btn_frame, text="新しいテスト", command=self.new_test).pack(side=tk.LEFT, padx=6)

        self.result_label = tk.Label(main_frame, text="", bg="#f8f9fc",
                                     font=("Noto Sans JP", 12, "bold"))
        self.result_label.pack(pady=(6, 0))

    def new_test(self):
        import random
        self.current_text = random.choice(self.TEXTS)
        self.target_label.config(text=self.current_text)
        self.input_text.delete("1.0", tk.END)
        self.input_text.config(state=tk.NORMAL, bg="white")
        self.input_text.focus()
        self.start_time = None
        self.result_label.config(text="")
        for lbl in self.stat_labels.values():
            lbl.config(text="--", fg="#3776ab")

    def on_type(self, event=None):
        typed = self.input_text.get("1.0", tk.END).rstrip("\n")
        if not typed:
            self.start_time = None
            return

        if self.start_time is None:
            self.start_time = time.time()

        elapsed = time.time() - self.start_time
        target = self.current_text

        # 正確率
        correct = sum(1 for a, b in zip(typed, target) if a == b)
        accuracy = correct / max(len(typed), 1) * 100

        # WPM
        words = len(typed.split())
        wpm = words / (elapsed / 60) if elapsed > 0 else 0

        # 進捗
        progress = len(typed) / len(target) * 100

        self.stat_labels["wpm"].config(text=f"{wpm:.0f}")
        self.stat_labels["accuracy"].config(text=f"{accuracy:.1f}%")
        self.stat_labels["elapsed"].config(text=f"{elapsed:.1f}秒")
        self.stat_labels["progress"].config(text=f"{min(progress, 100):.0f}%")

        # 完了判定
        if typed == target:
            self.input_text.config(bg="#d4edda")
            self.result_label.config(
                text=f"🎉 完了！ WPM: {wpm:.0f}  正確率: {accuracy:.1f}%  時間: {elapsed:.1f}秒",
                fg="#27ae60")
        elif not target.startswith(typed):
            self.input_text.config(bg="#f8d7da")
        else:
            self.input_text.config(bg="white")


if __name__ == "__main__":
    root = tk.Tk()
    app = App41(root)
    root.mainloop()
