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

class RandomRollCall:
    def __init__(self, root):
        self.root = root
        self.root.title("随机抽签点名器")
        self.root.geometry("680x520")
        self.root.resizable(False, False)

        # 数据存储
        self.name_list = []
        self.history = []
        self.is_rolling = False  # 是否正在滚动抽奖

        # 主界面布局
        self.create_widgets()

    def create_widgets(self):
        # 顶部抽签显示区域
        frame_top = tk.Frame(self.root, bg="#2c3e50", height=140)
        frame_top.pack(fill="x")
        frame_top.pack_propagate(False)

        self.show_label = tk.Label(
            frame_top, text="准备抽签", font=("微软雅黑", 48, "bold"),
            fg="white", bg="#2c3e50"
        )
        self.show_label.pack(expand=True)

        # 中部操作区
        frame_mid = tk.Frame(self.root, padx=15, pady=10)
        frame_mid.pack(fill="x")

        # 手动添加姓名
        tk.Label(frame_mid, text="添加姓名：", font=("微软雅黑", 11)).grid(row=0, column=0)
        self.entry_name = ttk.Entry(frame_mid, width=20, font=("微软雅黑", 11))
        self.entry_name.grid(row=0, column=1, padx=8)
        ttk.Button(frame_mid, text="添加", command=self.add_name).grid(row=0, column=2, padx=3)
        ttk.Button(frame_mid, text="导入txt名单", command=self.load_file).grid(row=0, column=3, padx=8)

        # 功能按钮行
        frame_btn = tk.Frame(self.root, padx=15)
        frame_btn.pack(fill="x", pady=6)
        self.btn_start = ttk.Button(frame_btn, text="开始抽签", command=self.start_roll, width=12)
        self.btn_start.grid(row=0, column=0, padx=5)
        ttk.Button(frame_btn, text="清空名单", command=self.clear_list).grid(row=0, column=1, padx=5)
        ttk.Button(frame_btn, text="清空记录", command=self.clear_history).grid(row=0, column=2, padx=5)
        ttk.Checkbutton(frame_btn, text="窗口置顶", command=self.set_top).grid(row=0, column=3, padx=10)

        # 左右分栏：名单列表 + 抽取历史
        frame_bottom = tk.Frame(self.root, padx=10)
        frame_bottom.pack(fill="both", expand=True)

        # 左侧名单
        frame_left = tk.LabelFrame(frame_bottom, text="全部名单", font=("微软雅黑", 10))
        frame_left.pack(side="left", fill="both", expand=True, padx=5)
        self.listbox_name = tk.Listbox(frame_left, font=("微软雅黑", 10))
        scroll1 = ttk.Scrollbar(frame_left, command=self.listbox_name.yview)
        self.listbox_name.config(yscrollcommand=scroll1.set)
        self.listbox_name.pack(side="left", fill="both", expand=True)
        scroll1.pack(side="right", fill="y")

        # 右侧历史记录
        frame_right = tk.LabelFrame(frame_bottom, text="抽签历史", font=("微软雅黑", 10))
        frame_right.pack(side="right", fill="both", expand=True, padx=5)
        self.listbox_history = tk.Listbox(frame_right, font=("微软雅黑", 10))
        scroll2 = ttk.Scrollbar(frame_right, command=self.listbox_history.yview)
        self.listbox_history.config(yscrollcommand=scroll2.set)
        self.listbox_history.pack(side="left", fill="both", expand=True)
        scroll2.pack(side="right", fill="y")

    # 手动添加单个名字
    def add_name(self):
        name = self.entry_name.get().strip()
        if not name:
            messagebox.showwarning("提示", "姓名不能为空")
            return
        if name not in self.name_list:
            self.name_list.append(name)
            self.listbox_name.insert(tk.END, name)
            self.entry_name.delete(0, tk.END)

    # 读取txt文件名单（一行一个名字）
    def load_file(self):
        path = filedialog.askopenfilename(filetypes=[("文本文件", "*.txt")])
        if not path:
            return
        try:
            with open(path, "r", encoding="utf-8") as f:
                lines = f.readlines()
                for line in lines:
                    name = line.strip()
                    if name and name not in self.name_list:
                        self.name_list.append(name)
                        self.listbox_name.insert(tk.END, name)
            messagebox.showinfo("成功", f"导入 {len(lines)} 条数据")
        except Exception as e:
            messagebox.showerror("读取失败", str(e))

    # 滚动动画线程
    def roll_animation(self):
        self.btn_start.config(state="disabled")
        count = 0
        # 滚动随机切换名字制造抽奖晃动效果
        while self.is_rolling and count < 35:
            random_name = random.choice(self.name_list)
            self.show_label.config(text=random_name, fg="#ffdd00")
            self.root.update()
            time.sleep(0.07)
            count += 1
        # 最终定格结果
        final_name = random.choice(self.name_list)
        self.show_label.config(text=final_name, fg="#00ff66")
        self.history.append(final_name)
        self.listbox_history.insert(tk.END, final_name)
        self.is_rolling = False
        self.btn_start.config(state="normal")

    # 触发抽签
    def start_roll(self):
        if len(self.name_list) == 0:
            messagebox.showwarning("警告", "名单为空，请先添加人员")
            return
        if self.is_rolling:
            return
        self.is_rolling = True
        # 新开线程防止界面卡死
        t = threading.Thread(target=self.roll_animation, daemon=True)
        t.start()

    # 清空所有名单
    def clear_list(self):
        self.name_list.clear()
        self.listbox_name.delete(0, tk.END)
        self.show_label.config(text="准备抽签", fg="white")

    # 清空历史记录
    def clear_history(self):
        self.history.clear()
        self.listbox_history.delete(0, tk.END)

    # 窗口置顶开关
    def set_top(self):
        top_flag = self.root.attributes("-topmost")
        self.root.attributes("-topmost", not top_flag)

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