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

class TimerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Tkinter 计时器")
        self.root.geometry("500x600")
        self.root.resizable(False, False)

        # 计时状态
        self.running = False
        self.start_time = 0
        self.elapsed_time = 0
        self.mode = 'stopwatch'  # 'stopwatch' 或 'countdown'
        self.countdown_seconds = 60
        self.laps = []
        self.job = None

        # 创建界面
        self.create_widgets()

    def create_widgets(self):
        # 模式选择
        mode_frame = ttk.LabelFrame(self.root, text="模式选择", padding=10)
        mode_frame.pack(fill="x", padx=20, pady=10)

        self.mode_var = tk.StringVar(value="stopwatch")
        ttk.Radiobutton(mode_frame, text="秒表", variable=self.mode_var, value="stopwatch",
                        command=self.switch_mode).pack(side="left", padx=20)
        ttk.Radiobutton(mode_frame, text="倒计时", variable=self.mode_var, value="countdown",
                        command=self.switch_mode).pack(side="left", padx=20)

        # 倒计时输入
        self.countdown_frame = ttk.Frame(mode_frame)
        self.countdown_frame.pack(side="right", padx=20)
        ttk.Label(self.countdown_frame, text="秒数:").pack(side="left")
        self.countdown_entry = ttk.Entry(self.countdown_frame, width=5)
        self.countdown_entry.insert(0, "60")
        self.countdown_entry.pack(side="left", padx=5)
        ttk.Button(self.countdown_frame, text="设置", command=self.set_countdown).pack(side="left")

        # 时间显示
        time_frame = ttk.Frame(self.root)
        time_frame.pack(pady=30)
        self.time_label = ttk.Label(time_frame, text="00:00:00", font=("Helvetica", 48, "bold"))
        self.time_label.pack()

        # 状态标签
        self.status_label = ttk.Label(self.root, text="未开始", font=("Helvetica", 14), foreground="gray")
        self.status_label.pack(pady=10)

        # 控制按钮
        btn_frame = ttk.Frame(self.root)
        btn_frame.pack(pady=20)
        ttk.Button(btn_frame, text="开始", command=self.start, width=10).pack(side="left", padx=10)
        ttk.Button(btn_frame, text="停止", command=self.stop, width=10).pack(side="left", padx=10)
        ttk.Button(btn_frame, text="重置", command=self.reset, width=10).pack(side="left", padx=10)
        ttk.Button(btn_frame, text="圈速", command=self.record_lap, width=10).pack(side="left", padx=10)

        # 圈速记录
        lap_frame = ttk.LabelFrame(self.root, text="圈速记录", padding=10)
        lap_frame.pack(fill="both", expand=True, padx=20, pady=10)

        self.lap_text = tk.Text(lap_frame, height=8, font=("Consolas", 11))
        self.lap_text.pack(fill="both", expand=True)
        scrollbar = ttk.Scrollbar(lap_frame, command=self.lap_text.yview)
        scrollbar.pack(side="right", fill="y")
        self.lap_text.config(yscrollcommand=scrollbar.set)

    def switch_mode(self):
        self.stop()
        self.reset()
        self.mode = self.mode_var.get()
        if self.mode == 'countdown':
            self.countdown_frame.pack_configure(side="right")
        else:
            self.countdown_frame.pack_forget()
        self.update_display()

    def set_countdown(self):
        try:
            self.countdown_seconds = int(self.countdown_entry.get())
            if self.countdown_seconds <= 0:
                raise ValueError
            self.elapsed_time = self.countdown_seconds * 1000
            self.update_display()
        except ValueError:
            messagebox.showerror("错误", "请输入有效的正整数秒数")

    def start(self):
        if not self.running:
            if self.mode == 'countdown' and self.elapsed_time <= 0:
                self.set_countdown()
            self.running = True
            self.start_time = time.time() * 1000 - self.elapsed_time
            self.status_label.config(text="运行中", foreground="green")
            self.update_timer()

    def stop(self):
        if self.running:
            self.running = False
            if self.job:
                self.root.after_cancel(self.job)
            self.elapsed_time = time.time() * 1000 - self.start_time
            self.status_label.config(text="已停止", foreground="red")
            self.update_display()

    def reset(self):
        self.stop()
        self.elapsed_time = 0
        self.laps = []
        self.lap_text.delete(1.0, tk.END)
        if self.mode == 'countdown':
            self.set_countdown()
        else:
            self.update_display()
        self.status_label.config(text="未开始", foreground="gray")

    def record_lap(self):
        if self.running and self.mode == 'stopwatch':
            current = time.time() * 1000 - self.start_time
            lap_time = current - (self.laps[-1] if self.laps else 0)
            self.laps.append(current)
            lap_num = len(self.laps)
            self.lap_text.insert(tk.END, f"圈 {lap_num}: {self.format_time(lap_time)}\n")
            self.lap_text.see(tk.END)

    def update_timer(self):
        if self.running:
            now = time.time() * 1000
            self.elapsed_time = now - self.start_time

            if self.mode == 'countdown':
                remaining = self.countdown_seconds * 1000 - self.elapsed_time
                if remaining <= 0:
                    self.elapsed_time = 0
                    self.running = False
                    self.status_label.config(text="时间到!", foreground="red")
                    self.root.bell()
                    messagebox.showinfo("提示", "倒计时结束！")
                else:
                    self.job = self.root.after(100, self.update_timer)
            else:
                self.job = self.root.after(100, self.update_timer)

            self.update_display()

    def update_display(self):
        if self.mode == 'countdown':
            display_time = max(0, self.countdown_seconds * 1000 - self.elapsed_time)
        else:
            display_time = self.elapsed_time
        self.time_label.config(text=self.format_time(display_time))

    def format_time(self, ms):
        total_seconds = int(ms // 1000)
        hours = total_seconds // 3600
        minutes = (total_seconds % 3600) // 60
        seconds = total_seconds % 60
        milliseconds = int((ms % 1000) // 10)
        if hours > 0:
            return f"{hours:02d}:{minutes:02d}:{seconds:02d}:{milliseconds:02d}"
        else:
            return f"{minutes:02d}:{seconds:02d}:{milliseconds:02d}"

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