import pygame
import sys
import random
import json
import os
import math
from datetime import datetime

# 初始化Pygame
pygame.init()

# 屏幕设置
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("🎯 随机点名器")

# 颜色
COLORS = {
    'background': (25, 30, 50),
    'panel_bg': (40, 45, 70),
    'panel_border': (70, 80, 120),
    'text_light': (230, 235, 245),
    'text_gold': (255, 215, 0),
    'text_green': (100, 255, 100),
    'text_red': (255, 100, 100),
    'button_bg': (60, 100, 180),
    'button_hover': (80, 130, 210),
    'button_pressed': (40, 70, 140),
    'button_green': (60, 180, 80),
    'button_green_hover': (80, 210, 100),
    'button_red': (200, 60, 60),
    'button_red_hover': (230, 80, 80),
    'button_orange': (200, 140, 40),
    'button_orange_hover': (230, 170, 60),
    'name_bg': (50, 55, 85),
    'history_bg': (35, 40, 65),
}

# ========== 中文字体 ==========
def get_chinese_font(size):
    font_paths = [
        "C:/Windows/Fonts/simsun.ttc",
        "C:/Windows/Fonts/simhei.ttf",
        "C:/Windows/Fonts/msyh.ttc",
        "C:/Windows/Fonts/STKAITI.TTF",
        "/System/Library/Fonts/PingFang.ttc",
        "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",
    ]
    for path in font_paths:
        try:
            if os.path.exists(path):
                return pygame.font.Font(path, size)
        except:
            continue
    return pygame.font.Font(None, size)

FONT_TITLE = get_chinese_font(48)
FONT_LARGE = get_chinese_font(36)
FONT_MEDIUM = get_chinese_font(24)
FONT_SMALL = get_chinese_font(18)
FONT_TINY = get_chinese_font(14)

class Button:
    def __init__(self, x, y, width, height, text, color, text_color=None):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.color = color
        self.text_color = text_color if text_color else COLORS['text_light']
        self.hover = False
        self.pressed = False
        self.visible = True
    
    def draw(self, surface):
        if not self.visible:
            return
        color = self.color
        if self.pressed:
            color = COLORS['button_pressed']
        elif self.hover:
            if self.color == COLORS['button_green']:
                color = COLORS['button_green_hover']
            elif self.color == COLORS['button_red']:
                color = COLORS['button_red_hover']
            elif self.color == COLORS['button_orange']:
                color = COLORS['button_orange_hover']
            else:
                color = COLORS['button_hover']
        
        pygame.draw.rect(surface, color, self.rect, border_radius=10)
        pygame.draw.rect(surface, COLORS['panel_border'], self.rect, 2, border_radius=10)
        
        text_surf = FONT_MEDIUM.render(self.text, True, self.text_color)
        text_rect = text_surf.get_rect(center=self.rect.center)
        surface.blit(text_surf, text_rect)
    
    def handle_event(self, event):
        if not self.visible:
            return False
        if event.type == pygame.MOUSEMOTION:
            self.hover = self.rect.collidepoint(event.pos)
            if not self.hover:
                self.pressed = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1 and self.rect.collidepoint(event.pos):
                self.pressed = True
                return True
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1 and self.pressed:
                self.pressed = False
                if self.rect.collidepoint(event.pos):
                    return True
        return False

class NameInput:
    """姓名输入框"""
    def __init__(self, x, y, width, height):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = ""
        self.active = False
        self.cursor_visible = True
        self.cursor_timer = 0
    
    def draw(self, surface):
        color = COLORS['text_gold'] if self.active else COLORS['panel_border']
        pygame.draw.rect(surface, COLORS['name_bg'], self.rect, border_radius=8)
        pygame.draw.rect(surface, color, self.rect, 2, border_radius=8)
        
        display_text = self.text
        if self.active and self.cursor_visible:
            display_text += "|"
        
        text_surf = FONT_MEDIUM.render(display_text, True, COLORS['text_light'])
        surface.blit(text_surf, (self.rect.x + 10, self.rect.y + 8))
    
    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            self.active = self.rect.collidepoint(event.pos)
            return self.active
        
        if self.active and event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN:
                if self.text.strip():
                    return True
            elif event.key == pygame.K_BACKSPACE:
                self.text = self.text[:-1]
            elif event.key == pygame.K_ESCAPE:
                self.active = False
            else:
                if len(self.text) < 20 and event.unicode.isprintable():
                    self.text += event.unicode
        return False
    
    def update(self):
        self.cursor_timer += 1
        if self.cursor_timer >= 30:
            self.cursor_timer = 0
            self.cursor_visible = not self.cursor_visible

class RandomPicker:
    """随机点名器主类"""
    def __init__(self):
        # 姓名列表
        self.names = []
        
        # 已点名历史
        self.history = []
        self.max_history = 50
        
        # 当前点名结果
        self.current_name = ""
        self.current_index = -1
        
        # 动画状态
        self.is_rolling = False
        self.roll_timer = 0
        self.roll_duration = 60  # 帧数
        self.roll_speed = 3
        self.display_name = ""
        
        # 粒子效果
        self.particles = []
        
        # 消息
        self.messages = []
        
        # 当前页面
        self.current_page = 'main'  # main, history
        
        # 初始化默认名单
        self.default_names = [
            "张三", "李四", "王五", "赵六", "孙七",
            "周八", "吴九", "郑十", "钱十一", "冯十二"
        ]
        self.names = self.default_names.copy()
        
        # ========== 按钮 ==========
        self.pick_button = Button(100, 450, 160, 55, "🎯 随机点名", COLORS['button_green'])
        self.add_button = Button(280, 450, 120, 55, "➕ 添加", COLORS['button_bg'])
        self.remove_button = Button(420, 450, 120, 55, "➖ 删除", COLORS['button_red'])
        self.clear_button = Button(560, 450, 120, 55, "🗑️ 清空", COLORS['button_red'])
        
        self.history_tab = Button(50, 540, 120, 40, "📜 历史", COLORS['button_bg'])
        self.back_button = Button(180, 540, 120, 40, "🔙 返回", COLORS['button_red'])
        self.back_button.visible = False
        self.clear_history_button = Button(320, 540, 140, 40, "🗑️ 清空历史", COLORS['button_red'])
        self.clear_history_button.visible = False
        
        # 输入框
        self.input_box = NameInput(100, 410, 300, 40)
        
        # 加载数据
        self.load_data()
        
        # 初始化显示
        if self.names:
            self.current_name = self.names[0]
            self.display_name = self.current_name
    
    def pick_random(self):
        """随机选择一个人"""
        if not self.names:
            self.add_message("⚠️ 名单为空! 请先添加姓名", COLORS['text_red'])
            return
        
        if self.is_rolling:
            return
        
        # 开始滚动动画
        self.is_rolling = True
        self.roll_timer = 0
        self.display_name = self.current_name
        
        # 记录到历史
        if self.current_name and self.current_name in self.names:
            self.history.append({
                'name': self.current_name,
                'time': datetime.now().strftime("%H:%M:%S")
            })
            if len(self.history) > self.max_history:
                self.history.pop(0)
            self.save_data()
    
    def update_roll(self):
        """更新滚动动画"""
        if not self.is_rolling:
            return
        
        self.roll_timer += 1
        
        # 在滚动过程中快速切换名字
        if self.roll_timer % self.roll_speed == 0:
            self.current_index = (self.current_index + 1) % len(self.names)
            self.display_name = self.names[self.current_index]
        
        # 结束时确定结果
        if self.roll_timer >= self.roll_duration:
            self.is_rolling = False
            # 最终选择
            self.current_index = random.randint(0, len(self.names) - 1)
            self.current_name = self.names[self.current_index]
            self.display_name = self.current_name
            
            # 记录历史
            self.history.append({
                'name': self.current_name,
                'time': datetime.now().strftime("%H:%M:%S")
            })
            if len(self.history) > self.max_history:
                self.history.pop(0)
            
            # 粒子效果
            for _ in range(50):
                angle = random.uniform(0, 2 * math.pi)
                speed = random.uniform(3, 10)
                self.particles.append({
                    'x': WINDOW_WIDTH // 2,
                    'y': 250,
                    'vx': math.cos(angle) * speed,
                    'vy': math.sin(angle) * speed - 3,
                    'size': random.randint(4, 10),
                    'color': (random.randint(200, 255), random.randint(200, 255), random.randint(100, 255)),
                    'life': 50,
                    'max_life': 50
                })
            
            self.add_message(f"🎯 点到: {self.current_name}", COLORS['text_gold'])
            self.save_data()
    
    def add_name(self):
        """添加姓名"""
        name = self.input_box.text.strip()
        if not name:
            self.add_message("⚠️ 请输入姓名!", COLORS['text_red'])
            return
        
        if name in self.names:
            self.add_message(f"⚠️ {name} 已存在!", COLORS['text_red'])
            return
        
        self.names.append(name)
        self.input_box.text = ""
        self.add_message(f"✅ 已添加: {name}", COLORS['text_green'])
        self.save_data()
        
        # 如果当前没有选中的人，选中第一个
        if not self.current_name and self.names:
            self.current_name = self.names[0]
            self.display_name = self.current_name
    
    def remove_name(self):
        """删除选中的姓名"""
        if not self.names:
            self.add_message("⚠️ 名单为空!", COLORS['text_red'])
            return
        
        if not self.current_name:
            self.current_name = self.names[0]
        
        if self.current_name in self.names:
            self.names.remove(self.current_name)
            self.add_message(f"🗑️ 已删除: {self.current_name}", COLORS['text_red'])
            
            if self.names:
                self.current_name = self.names[0]
                self.display_name = self.current_name
            else:
                self.current_name = ""
                self.display_name = ""
            
            self.save_data()
    
    def clear_names(self):
        """清空名单"""
        if not self.names:
            self.add_message("⚠️ 名单已空!", COLORS['text_red'])
            return
        
        self.names = []
        self.current_name = ""
        self.display_name = ""
        self.add_message("🗑️ 已清空名单", COLORS['text_red'])
        self.save_data()
    
    def clear_history(self):
        """清空历史记录"""
        if not self.history:
            self.add_message("⚠️ 历史记录已空!", COLORS['text_red'])
            return
        
        self.history = []
        self.add_message("🗑️ 已清空历史记录", COLORS['text_red'])
        self.save_data()
    
    def add_message(self, text, color=COLORS['text_light']):
        self.messages.append({'text': text, 'color': color, 'time': 120})
        if len(self.messages) > 10:
            self.messages.pop(0)
    
    def go_to_page(self, page):
        self.current_page = page
        self.back_button.visible = (page == 'history')
        self.clear_history_button.visible = (page == 'history')
    
    def save_data(self):
        """保存数据"""
        try:
            data = {
                'names': self.names,
                'history': self.history,
            }
            with open('picker_data.json', 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存失败: {e}")
    
    def load_data(self):
        """加载数据"""
        try:
            if os.path.exists('picker_data.json'):
                with open('picker_data.json', 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    if 'names' in data and data['names']:
                        self.names = data['names']
                    if 'history' in data:
                        self.history = data['history']
                
                if self.names:
                    self.current_name = self.names[0]
                    self.display_name = self.current_name
        except Exception as e:
            print(f"加载失败: {e}")
    
    def update(self):
        """更新游戏状态"""
        self.update_roll()
        self.input_box.update()
        
        # 更新粒子
        for p in self.particles[:]:
            p['x'] += p['vx']
            p['y'] += p['vy']
            p['vy'] += 0.15
            p['life'] -= 1
            if p['life'] <= 0:
                self.particles.remove(p)
        
        # 消息
        for msg in self.messages:
            msg['time'] -= 1
        self.messages = [m for m in self.messages if m['time'] > 0]
    
    def draw(self, surface):
        surface.fill(COLORS['background'])
        
        # 标题
        title = FONT_TITLE.render("🎯 随机点名器", True, COLORS['text_gold'])
        title_rect = title.get_rect(center=(WINDOW_WIDTH // 2, 50))
        surface.blit(title, title_rect)
        
        # 统计信息
        count_text = FONT_SMALL.render(f"👥 总人数: {len(self.names)}", True, COLORS['text_light'])
        surface.blit(count_text, (30, 90))
        
        # 显示当前名字
        self.draw_name_display(surface)
        
        if self.current_page == 'main':
            self.draw_main(surface)
        elif self.current_page == 'history':
            self.draw_history(surface)
        
        # 导航
        self.draw_navigation(surface)
        
        # 消息
        self.draw_messages(surface)
    
    def draw_name_display(self, surface):
        """绘制名字显示区域"""
        rect = pygame.Rect(150, 120, 500, 200)
        pygame.draw.rect(surface, COLORS['panel_bg'], rect, border_radius=20)
        pygame.draw.rect(surface, COLORS['panel_border'], rect, 3, border_radius=20)
        
        # 名字
        name = self.display_name if self.display_name else "请添加姓名"
        color = COLORS['text_gold'] if self.display_name else COLORS['text_light']
        font = FONT_TITLE if len(name) <= 4 else FONT_LARGE
        text = font.render(name, True, color)
        text_rect = text.get_rect(center=(WINDOW_WIDTH // 2, 220))
        surface.blit(text, text_rect)
        
        # 滚动状态提示
        if self.is_rolling:
            roll_text = FONT_SMALL.render("🎰 抽选中...", True, COLORS['text_green'])
            surface.blit(roll_text, (WINDOW_WIDTH // 2 - 60, 290))
    
    def draw_main(self, surface):
        """绘制主界面"""
        # 输入框
        self.input_box.draw(surface)
        
        # 按钮
        self.pick_button.draw(surface)
        self.add_button.draw(surface)
        self.remove_button.draw(surface)
        self.clear_button.draw(surface)
        
        # 姓名列表预览
        self.draw_name_list(surface)
    
    def draw_name_list(self, surface):
        """绘制姓名列表预览"""
        rect = pygame.Rect(30, 490, 740, 40)
        pygame.draw.rect(surface, COLORS['name_bg'], rect, border_radius=8)
        
        if not self.names:
            text = FONT_SMALL.render("暂无姓名，请添加", True, (150, 150, 180))
            surface.blit(text, (50, 500))
        else:
            # 显示前几个姓名
            display_names = self.names[:10]
            if len(self.names) > 10:
                display_names.append(f"... 共{len(self.names)}人")
            
            x = 50
            for name in display_names:
                if name.startswith("..."):
                    color = (150, 150, 180)
                else:
                    color = COLORS['text_gold'] if name == self.current_name else COLORS['text_light']
                text = FONT_TINY.render(name, True, color)
                surface.blit(text, (x, 500))
                x += text.get_width() + 20
    
    def draw_history(self, surface):
        """绘制历史记录"""
        rect = pygame.Rect(50, 100, 700, 400)
        pygame.draw.rect(surface, COLORS['history_bg'], rect, border_radius=15)
        pygame.draw.rect(surface, COLORS['panel_border'], rect, 2, border_radius=15)
        
        title = FONT_LARGE.render("📜 点名历史", True, COLORS['text_gold'])
        surface.blit(title, (70, 115))
        
        if not self.history:
            empty_text = FONT_MEDIUM.render("暂无历史记录", True, (150, 150, 180))
            surface.blit(empty_text, (300, 280))
            return
        
        # 显示历史记录（最新的在上面）
        y = 160
        for i, record in enumerate(reversed(self.history[-20:])):
            color = (200, 200, 220) if i % 2 == 0 else (180, 180, 200)
            
            # 序号
            num_text = FONT_SMALL.render(f"#{len(self.history) - i}", True, (150, 150, 180))
            surface.blit(num_text, (70, y))
            
            # 姓名
            name_text = FONT_MEDIUM.render(record['name'], True, COLORS['text_gold'])
            surface.blit(name_text, (130, y - 2))
            
            # 时间
            time_text = FONT_SMALL.render(record.get('time', ''), True, (150, 150, 180))
            surface.blit(time_text, (250, y + 2))
            
            y += 35
            if y > 450:
                break
    
    def draw_navigation(self, surface):
        """绘制导航栏"""
        nav_rect = pygame.Rect(0, 530, WINDOW_WIDTH, 70)
        pygame.draw.rect(surface, COLORS['panel_bg'], nav_rect)
        pygame.draw.line(surface, COLORS['panel_border'], (0, 530), (WINDOW_WIDTH, 530), 2)
        
        self.history_tab.draw(surface)
        self.back_button.draw(surface)
        self.clear_history_button.draw(surface)
    
    def draw_messages(self, surface):
        """绘制消息"""
        y = 565
        for msg in reversed(self.messages[-4:]):
            alpha = min(255, msg['time'] * 2)
            text = FONT_SMALL.render(msg['text'], True, msg['color'])
            text.set_alpha(alpha)
            surface.blit(text, (500, y))
            y -= 26

def main():
    clock = pygame.time.Clock()
    picker = RandomPicker()
    running = True
    
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                picker.save_data()
                running = False
            
            # 输入框事件
            if picker.input_box.handle_event(event):
                if picker.current_page == 'main':
                    picker.add_name()
            
            # 按钮事件
            if picker.pick_button.handle_event(event):
                if picker.current_page == 'main':
                    picker.pick_random()
            
            if picker.add_button.handle_event(event):
                if picker.current_page == 'main':
                    picker.add_name()
            
            if picker.remove_button.handle_event(event):
                if picker.current_page == 'main':
                    picker.remove_name()
            
            if picker.clear_button.handle_event(event):
                if picker.current_page == 'main':
                    picker.clear_names()
            
            if picker.history_tab.handle_event(event):
                picker.go_to_page('history')
            
            if picker.back_button.handle_event(event):
                picker.go_to_page('main')
            
            if picker.clear_history_button.handle_event(event):
                if picker.current_page == 'history':
                    picker.clear_history()
        
        picker.update()
        
        # 绘制粒子
        picker.draw(screen)
        for p in picker.particles:
            alpha = int(255 * p['life'] / p['max_life'])
            color = (*p['color'], alpha)
            pygame.draw.circle(screen, p['color'], (int(p['x']), int(p['y'])), int(p['size'] * p['life'] / p['max_life']))
        
        pygame.display.flip()
        clock.tick(60)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()