import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import random
import time
import json
import os
from tkinter.font import Font

class RandomNamePicker:
    def __init__(self, root):
        self.root = root
        self.root.title("随机点名/抽签系统")
        self.root.geometry("900x700")
        self.root.configure(bg='#f0f8ff')
        
        # 设置图标
        try:
            self.root.iconbitmap(default=None)
        except:
            pass
        
        # 初始化变量
        self.names = []
        self.history = []
        self.selected_names = []
        self.is_rolling = False
        self.current_index = 0
        self.selected_count = 0
        
        # 创建自定义字体
        self.title_font = Font(family="Microsoft YaHei", size=24, weight="bold")
        self.name_font = Font(family="Microsoft YaHei", size=36, weight="bold")
        self.normal_font = Font(family="Microsoft YaHei", size=12)
        self.small_font = Font(family="Microsoft YaHei", size=10)
        
        # 设置样式
        self.setup_styles()
        
        # 创建界面
        self.setup_ui()
        
        # 加载默认数据
        self.load_default_names()
    
    def setup_styles(self):
        """设置样式"""
        style = ttk.Style()
        style.theme_use('clam')
        
        # 配置按钮样式
        style.configure('Primary.TButton', 
                       font=self.normal_font,
                       padding=10,
                       background='#4CAF50',
                       foreground='white')
        style.map('Primary.TButton',
                 background=[('active', '#45a049')])
        
        style.configure('Secondary.TButton',
                       font=self.normal_font,
                       padding=8,
                       background='#2196F3',
                       foreground='white')
        style.map('Secondary.TButton',
                 background=[('active', '#0b7dda')])
        
        style.configure('Danger.TButton',
                       font=self.normal_font,
                       padding=8,
                       background='#f44336',
                       foreground='white')
        style.map('Danger.TButton',
                 background=[('active', '#da190b')])
        
        # 配置标签样式
        style.configure('Header.TLabel',
                      font=('Microsoft YaHei', 16, 'bold'),
                      background='#f0f8ff',
                      foreground='#333')
        
        # 配置框架样式
        style.configure('Card.TFrame',
                       background='white',
                       relief='solid',
                       borderwidth=1)
    
    def setup_ui(self):
        """设置用户界面"""
        # 主容器
        main_frame = ttk.Frame(self.root, padding="20")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 标题
        title_label = ttk.Label(main_frame, 
                               text="🎲 随机点名/抽签系统 🎲", 
                               font=self.title_font,
                               background='#f0f8ff',
                               foreground='#2c3e50')
        title_label.grid(row=0, column=0, columnspan=3, pady=(0, 20))
        
        # 创建左右两个主区域
        left_frame = ttk.Frame(main_frame, style='Card.TFrame', padding="15")
        left_frame.grid(row=1, column=0, rowspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(0, 10))
        
        right_frame = ttk.Frame(main_frame, style='Card.TFrame', padding="15")
        right_frame.grid(row=1, column=1, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 配置网格权重
        main_frame.columnconfigure(0, weight=1)
        main_frame.columnconfigure(1, weight=2)
        main_frame.rowconfigure(1, weight=1)
        
        # 左侧：名单管理区域
        self.setup_left_panel(left_frame)
        
        # 右侧：显示和操作区域
        self.setup_right_panel(right_frame)
        
        # 底部：历史记录区域
        self.setup_bottom_panel(main_frame)
        
        # 设置最小大小
        self.root.minsize(800, 650)
    
    def setup_left_panel(self, parent):
        """设置左侧面板（名单管理）"""
        # 标题
        ttk.Label(parent, 
                 text="📋 名单管理", 
                 style='Header.TLabel').grid(row=0, column=0, columnspan=2, sticky=tk.W, pady=(0, 10))
        
        # 文本输入框
        ttk.Label(parent, 
                 text="添加姓名（每行一个）:", 
                 font=self.normal_font).grid(row=1, column=0, columnspan=2, sticky=tk.W, pady=(5, 5))
        
        self.text_input = tk.Text(parent, height=8, width=25, font=self.normal_font, 
                                 bg='white', fg='#333', relief='solid', borderwidth=1)
        self.text_input.grid(row=2, column=0, columnspan=2, pady=(0, 10))
        
        # 按钮框架
        btn_frame = ttk.Frame(parent)
        btn_frame.grid(row=3, column=0, columnspan=2, pady=(0, 10))
        
        ttk.Button(btn_frame, 
                  text="添加名单", 
                  style='Primary.TButton',
                  command=self.add_names).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(btn_frame, 
                  text="清空名单", 
                  style='Danger.TButton',
                  command=self.clear_names).pack(side=tk.LEFT)
        
        # 名单列表
        ttk.Label(parent, 
                 text="当前名单列表:", 
                 font=self.normal_font).grid(row=4, column=0, columnspan=2, sticky=tk.W, pady=(10, 5))
        
        # 创建滚动条
        list_frame = ttk.Frame(parent)
        list_frame.grid(row=5, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        scrollbar = ttk.Scrollbar(list_frame)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        self.name_listbox = tk.Listbox(list_frame, 
                                      height=8, 
                                      font=self.normal_font,
                                      bg='white',
                                      fg='#333',
                                      selectbackground='#e3f2fd',
                                      selectforeground='#1565c0',
                                      yscrollcommand=scrollbar.set)
        self.name_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.config(command=self.name_listbox.yview)
        
        # 文件操作按钮框架
        file_frame = ttk.Frame(parent)
        file_frame.grid(row=6, column=0, columnspan=2, pady=(10, 0))
        
        ttk.Button(file_frame, 
                  text="导入名单", 
                  style='Secondary.TButton',
                  command=self.import_names).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(file_frame, 
                  text="导出名单", 
                  style='Secondary.TButton',
                  command=self.export_names).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(file_frame, 
                  text="保存配置", 
                  style='Secondary.TButton',
                  command=self.save_config).pack(side=tk.LEFT)
    
    def setup_right_panel(self, parent):
        """设置右侧面板（显示和操作）"""
        # 结果显示区域
        result_frame = ttk.Frame(parent, style='Card.TFrame')
        result_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 20))
        
        ttk.Label(result_frame, 
                 text="🎯 抽签结果", 
                 style='Header.TLabel').pack(pady=(10, 20))
        
        # 结果显示标签
        self.result_label = tk.Label(result_frame, 
                                    text="点击开始按钮", 
                                    font=self.name_font,
                                    bg='white',
                                    fg='#3498db',
                                    width=20,
                                    height=3,
                                    relief='solid',
                                    borderwidth=2)
        self.result_label.pack(pady=(0, 20), padx=20)
        
        # 统计信息
        stats_frame = ttk.Frame(result_frame)
        stats_frame.pack(pady=(0, 20))
        
        self.stats_label = ttk.Label(stats_frame, 
                                    text="总人数: 0 | 已选: 0 | 剩余: 0", 
                                    font=('Microsoft YaHei', 12))
        self.stats_label.pack()
        
        # 控制按钮区域
        control_frame = ttk.Frame(parent)
        control_frame.grid(row=1, column=0, columnspan=2, pady=(10, 0))
        
        # 第一行按钮
        btn_row1 = ttk.Frame(control_frame)
        btn_row1.pack(pady=(0, 10))
        
        self.start_btn = ttk.Button(btn_row1, 
                                   text="▶ 开始随机", 
                                   style='Primary.TButton',
                                   command=self.toggle_roll,
                                   width=15)
        self.start_btn.pack(side=tk.LEFT, padx=5)
        
        ttk.Button(btn_row1, 
                  text="🎯 选择一人", 
                  style='Secondary.TButton',
                  command=self.select_one,
                  width=15).pack(side=tk.LEFT, padx=5)
        
        ttk.Button(btn_row1, 
                  text="🎪 选择多人", 
                  style='Secondary.TButton',
                  command=self.select_multiple,
                  width=15).pack(side=tk.LEFT, padx=5)
        
        # 第二行按钮
        btn_row2 = ttk.Frame(control_frame)
        btn_row2.pack()
        
        ttk.Button(btn_row2, 
                  text="🔄 重置选择", 
                  style='Secondary.TButton',
                  command=self.reset_selection,
                  width=15).pack(side=tk.LEFT, padx=5)
        
        ttk.Button(btn_row2, 
                  text="🎲 随机排序", 
                  style='Secondary.TButton',
                  command=self.randomize_list,
                  width=15).pack(side=tk.LEFT, padx=5)
        
        ttk.Button(btn_row2, 
                  text="🗑️ 清空历史", 
                  style='Danger.TButton',
                  command=self.clear_history,
                  width=15).pack(side=tk.LEFT, padx=5)
        
        # 设置列权重
        parent.columnconfigure(0, weight=1)
        parent.columnconfigure(1, weight=1)
    
    def setup_bottom_panel(self, parent):
        """设置底部面板（历史记录）"""
        bottom_frame = ttk.Frame(parent, style='Card.TFrame', padding="15")
        bottom_frame.grid(row=2, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(10, 0))
        
        ttk.Label(bottom_frame, 
                 text="📜 选择历史", 
                 style='Header.TLabel').grid(row=0, column=0, sticky=tk.W, pady=(0, 10))
        
        # 创建滚动条
        history_frame = ttk.Frame(bottom_frame)
        history_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        history_scrollbar = ttk.Scrollbar(history_frame)
        history_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        self.history_listbox = tk.Listbox(history_frame, 
                                         height=6, 
                                         font=self.normal_font,
                                         bg='white',
                                         fg='#333',
                                         yscrollcommand=history_scrollbar.set)
        self.history_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        history_scrollbar.config(command=self.history_listbox.yview)
        
        # 配置权重
        parent.rowconfigure(2, weight=1)
        bottom_frame.columnconfigure(0, weight=1)
    
    def load_default_names(self):
        """加载默认名单"""
        default_names = [
            "张三", "李四", "王五", "赵六", "钱七",
            "孙八", "周九", "吴十", "郑十一", "王十二",
            "刘十三", "陈十四", "杨十五", "黄十六", "朱十七"
        ]
        self.names = default_names.copy()
        self.update_name_listbox()
        self.update_stats()
    
    def add_names(self):
        """添加新名字到名单"""
        text = self.text_input.get("1.0", tk.END).strip()
        if text:
            new_names = [name.strip() for name in text.split('\n') if name.strip()]
            for name in new_names:
                if name not in self.names:
                    self.names.append(name)
            self.update_name_listbox()
            self.update_stats()
            self.text_input.delete("1.0", tk.END)
            messagebox.showinfo("成功", f"成功添加 {len(new_names)} 个新名字")
        else:
            messagebox.showwarning("提示", "请输入要添加的名字")
    
    def clear_names(self):
        """清空名单"""
        if messagebox.askyesno("确认", "确定要清空所有名单吗？"):
            self.names.clear()
            self.selected_names.clear()
            self.update_name_listbox()
            self.update_stats()
            self.result_label.config(text="名单已清空", fg='#e74c3c')
    
    def import_names(self):
        """从文件导入名单"""
        filepath = filedialog.askopenfilename(
            title="选择名单文件",
            filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
        )
        if filepath:
            try:
                with open(filepath, 'r', encoding='utf-8') as f:
                    content = f.read()
                imported_names = [name.strip() for name in content.split('\n') if name.strip()]
                new_count = 0
                for name in imported_names:
                    if name not in self.names:
                        self.names.append(name)
                        new_count += 1
                self.update_name_listbox()
                self.update_stats()
                messagebox.showinfo("成功", f"成功导入 {new_count} 个新名字")
            except Exception as e:
                messagebox.showerror("错误", f"导入文件时出错：{str(e)}")
    
    def export_names(self):
        """导出名单到文件"""
        if not self.names:
            messagebox.showwarning("提示", "名单为空，无法导出")
            return
        
        filepath = filedialog.asksaveasfilename(
            title="保存名单文件",
            defaultextension=".txt",
            filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
        )
        if filepath:
            try:
                with open(filepath, 'w', encoding='utf-8') as f:
                    for name in self.names:
                        f.write(f"{name}\n")
                messagebox.showinfo("成功", f"名单已成功导出到：{filepath}")
            except Exception as e:
                messagebox.showerror("错误", f"导出文件时出错：{str(e)}")
    
    def save_config(self):
        """保存配置到文件"""
        config = {
            'names': self.names,
            'history': self.history[-20:]  # 只保存最近20条历史记录
        }
        
        filepath = filedialog.asksaveasfilename(
            title="保存配置",
            defaultextension=".json",
            filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")]
        )
        if filepath:
            try:
                with open(filepath, 'w', encoding='utf-8') as f:
                    json.dump(config, f, ensure_ascii=False, indent=2)
                messagebox.showinfo("成功", f"配置已保存到：{filepath}")
            except Exception as e:
                messagebox.showerror("错误", f"保存配置时出错：{str(e)}")
    
    def update_name_listbox(self):
        """更新名单列表框"""
        self.name_listbox.delete(0, tk.END)
        for i, name in enumerate(self.names, 1):
            if name in self.selected_names:
                self.name_listbox.insert(tk.END, f"✓ {i}. {name}")
                self.name_listbox.itemconfig(tk.END, {'fg': '#95a5a6'})
            else:
                self.name_listbox.insert(tk.END, f"{i}. {name}")
    
    def update_stats(self):
        """更新统计信息"""
        total = len(self.names)
        selected = len(self.selected_names)
        remaining = total - selected
        
        self.stats_label.config(
            text=f"总人数: {total} | 已选: {selected} | 剩余: {remaining}"
        )
    
    def toggle_roll(self):
        """开始/停止随机滚动"""
        if not self.names:
            messagebox.showwarning("提示", "名单为空，请先添加名字")
            return
        
        if not self.is_rolling:
            # 开始滚动
            self.is_rolling = True
            self.start_btn.config(text="⏸ 停止随机")
            self.roll_names()
        else:
            # 停止滚动
            self.is_rolling = False
            self.start_btn.config(text="▶ 开始随机")
            
            # 从剩余名单中选择
            remaining_names = [name for name in self.names if name not in self.selected_names]
            if remaining_names:
                selected_name = random.choice(remaining_names)
                self.selected_names.append(selected_name)
                self.add_to_history(selected_name)
                self.result_label.config(text=selected_name, fg='#e74c3c')
                
                # 更新显示
                self.update_name_listbox()
                self.update_stats()
            else:
                messagebox.showinfo("提示", "所有人员都已被选择！")
                self.result_label.config(text="全部完成！", fg='#2ecc71')
    
    def roll_names(self):
        """随机滚动显示名字"""
        if self.is_rolling:
            remaining_names = [name for name in self.names if name not in self.selected_names]
            if remaining_names:
                # 随机显示一个名字
                random_name = random.choice(remaining_names)
                self.result_label.config(text=random_name, fg='#3498db')
                
                # 继续滚动
                self.root.after(100, self.roll_names)
            else:
                self.is_rolling = False
                self.start_btn.config(text="▶ 开始随机")
                self.result_label.config(text="全部完成！", fg='#2ecc71')
    
    def select_one(self):
        """随机选择一人"""
        if not self.names:
            messagebox.showwarning("提示", "名单为空，请先添加名字")
            return
        
        remaining_names = [name for name in self.names if name not in self.selected_names]
        if remaining_names:
            selected_name = random.choice(remaining_names)
            self.selected_names.append(selected_name)
            self.add_to_history(selected_name)
            self.result_label.config(text=selected_name, fg='#e74c3c')
            
            # 更新显示
            self.update_name_listbox()
            self.update_stats()
        else:
            messagebox.showinfo("提示", "所有人员都已被选择！")
            self.result_label.config(text="全部完成！", fg='#2ecc71')
    
    def select_multiple(self):
        """随机选择多人"""
        if not self.names:
            messagebox.showwarning("提示", "名单为空，请先添加名字")
            return
        
        remaining_names = [name for name in self.names if name not in self.selected_names]
        if not remaining_names:
            messagebox.showinfo("提示", "所有人员都已被选择！")
            self.result_label.config(text="全部完成！", fg='#2ecc71')
            return
        
        # 创建选择对话框
        select_dialog = tk.Toplevel(self.root)
        select_dialog.title("选择多人")
        select_dialog.geometry("300x200")
        select_dialog.configure(bg='white')
        select_dialog.transient(self.root)
        select_dialog.grab_set()
        
        # 居中对话框
        select_dialog.geometry(f"+{self.root.winfo_rootx()+300}+{self.root.winfo_rooty()+200}")
        
        ttk.Label(select_dialog, 
                 text="选择人数:", 
                 font=self.normal_font,
                 background='white').pack(pady=20)
        
        # 人数选择
        count_var = tk.IntVar(value=1)
        count_spinbox = ttk.Spinbox(select_dialog, 
                                   from_=1, 
                                   to=min(10, len(remaining_names)), 
                                   textvariable=count_var,
                                   font=self.normal_font,
                                   width=10)
        count_spinbox.pack(pady=10)
        
        # 按钮框架
        btn_frame = ttk.Frame(select_dialog)
        btn_frame.pack(pady=20)
        
        def confirm_selection():
            count = count_var.get()
            if count > len(remaining_names):
                messagebox.showwarning("提示", f"最多只能选择 {len(remaining_names)} 人")
                return
            
            selected = random.sample(remaining_names, count)
            for name in selected:
                self.selected_names.append(name)
                self.add_to_history(name, is_multiple=True)
            
            if count == 1:
                self.result_label.config(text=selected[0], fg='#e74c3c')
            else:
                self.result_label.config(text=f"已选择 {count} 人", fg='#e74c3c')
            
            # 更新显示
            self.update_name_listbox()
            self.update_stats()
            select_dialog.destroy()
        
        ttk.Button(btn_frame, 
                  text="确定", 
                  style='Primary.TButton',
                  command=confirm_selection).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, 
                  text="取消", 
                  command=select_dialog.destroy).pack(side=tk.LEFT, padx=5)
    
    def reset_selection(self):
        """重置选择"""
        if not self.selected_names:
            messagebox.showinfo("提示", "当前没有已选择的人员")
            return
        
        if messagebox.askyesno("确认", "确定要重置所有选择吗？"):
            self.selected_names.clear()
            self.result_label.config(text="选择已重置", fg='#3498db')
            self.update_name_listbox()
            self.update_stats()
    
    def randomize_list(self):
        """随机排序名单"""
        if len(self.names) < 2:
            messagebox.showinfo("提示", "名单人数不足，无法随机排序")
            return
        
        random.shuffle(self.names)
        self.update_name_listbox()
        self.result_label.config(text="已随机排序", fg='#9b59b6')
    
    def clear_history(self):
        """清空历史记录"""
        if not self.history:
            messagebox.showinfo("提示", "历史记录为空")
            return
        
        if messagebox.askyesno("确认", "确定要清空历史记录吗？"):
            self.history.clear()
            self.history_listbox.delete(0, tk.END)
    
    def add_to_history(self, name, is_multiple=False):
        """添加选择记录到历史"""
        from datetime import datetime
        timestamp = datetime.now().strftime("%H:%M:%S")
        
        if is_multiple:
            history_entry = f"{timestamp} - 选择了多人"
        else:
            history_entry = f"{timestamp} - 选择了: {name}"
        
        self.history.append(history_entry)
        self.history_listbox.insert(0, history_entry)
        
        # 限制历史记录数量
        if len(self.history) > 50:
            self.history.pop()
            self.history_listbox.delete(tk.END)

def main():
    """主函数"""
    root = tk.Tk()
    
    # 设置窗口图标
    try:
        root.iconbitmap(default=None)
    except:
        pass
    
    # 设置窗口位置居中
    window_width = 900
    window_height = 700
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    center_x = int(screen_width/2 - window_width/2)
    center_y = int(screen_height/2 - window_height/2)
    root.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')
    
    # 创建应用
    app = RandomNamePicker(root)
    
    # 运行主循环
    root.mainloop()

if __name__ == "__main__":
    main()